3D scatter plot with color gradient
Asked Answered
R

2

23

How can I create a 3D plot with a color gradient for the points? See the example below, which works for a 2D scatter plot.

Edit (thanks to Chris): What I'm expecting to see from the 3D plot is a color gradient of the points ranging from red to green as in the 2D scatter plot. What I see in the 3D scatter plot are only red points.

Solution: for some reasons (related to the gradient example I copied elsewhere) I set xrange to len-1, which messes everything in the 3D plot.

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# Create Map
cm = plt.get_cmap("RdYlGn")

x = np.random.rand(30)
y = np.random.rand(30)
z = np.random.rand(30)
#col = [cm(float(i)/(29)) for i in xrange(29)] # BAD!!!
col = [cm(float(i)/(30)) for i in xrange(30)]

# 2D Plot
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(x, y, s=10, c=col, marker='o')  

# 3D Plot
fig = plt.figure()
ax3D = fig.add_subplot(111, projection='3d')
ax3D.scatter(x, y, z, s=10, c=col, marker='o')  

plt.show()
Rafa answered 17/1, 2012 at 9:8 Comment(3)
What's wrong with the 3D scatter plot? What do you expect to see from it and what do you actually see? From you code your call to Axes3D.scatter seems ok.Stomach
What I'm expecting to see from the 3D plot is a color gradient of the points ranging from red to green as in the 2D scatter plot. What I see in the 3D scatter plot are only red points.Rafa
Answer to a similar questionSeng
A
29

Here is an example for 3d scatter with gradient colors:

import matplotlib.cm as cmx
from mpl_toolkits.mplot3d import Axes3D
def scatter3d(x,y,z, cs, colorsMap='jet'):
    cm = plt.get_cmap(colorsMap)
    cNorm = matplotlib.colors.Normalize(vmin=min(cs), vmax=max(cs))
    scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=cm)
    fig = plt.figure()
    ax = Axes3D(fig)
    ax.scatter(x, y, z, c=scalarMap.to_rgba(cs))
    scalarMap.set_array(cs)
    fig.colorbar(scalarMap)
    plt.show()

Of course, you can choose the scale to range between different values, like 0 and 1.

Attempt answered 27/11, 2014 at 21:59 Comment(4)
ax.scatter(z, y, z, c=scalarMap.to_rgba(cs)) should be ax.scatter(x, y, z, c=scalarMap.to_rgba(cs))Lochner
@NoamPeled What does cs mean?Patricepatrich
It's the values for each 3D point. If colors_data is a 3D matrix, with a value for each 3D point, X is a Nx3 matrix of list of x,y,z coordinates, so cs=[colors_data[x, y, z] for x,y,z in zip(X[:, 0], X[:, 1], X[:, 2])]Attempt
@NoamPeled the 3d plot tends to alter the relative aspect ratio of the axes. Is it possible to prevent this? looks awkward if one of the dimensions is much larger than the other?Stearns
B
5

Following works: I can't figure out why yours doesn't. You should be able to set color as a sequence of RGBA floats, or just sequence of floats.

# Create Map
cm = plt.get_cmap("RdYlGn")

x = np.random.rand(30)
y = np.random.rand(30)
z = np.random.rand(30)
col = np.arange(30)

# 2D Plot
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(x, y, s=10, c=col, marker='o')  

# 3D Plot
fig = plt.figure()
ax3D = fig.add_subplot(111, projection='3d')
p3d = ax3D.scatter(x, y, z, s=30, c=col, marker='o')                                                                                

plt.show()

However, in help of scatter, I see the following, it may be related.

    A :class:`matplotlib.colors.Colormap` instance or registered
    name. If *None*, defaults to rc ``image.cmap``. *cmap* is
    only used if *c* is an array of floats.
Bellyache answered 17/1, 2012 at 9:58 Comment(2)
Adding ", cmap=cm" (ax3D.scatter(x, y, z, s=30, c=col, marker='o', cmap=cm)) to the scatter function I have the color gradient back also in the 3D scatter plot. What I miss now seems to be the depth, but I guess I can not have both.Rafa
what do you mean you don't have depth?Bellyache

© 2022 - 2024 — McMap. All rights reserved.