5

I have four dimensional data (x, y, z displacements; and respective voltages) which I wish to plot in a 3d scatterplot in python. I've gotten the 3d plot to render, but I want to have the colour of the points change using a colourmap, dependent upon the magnitude of the point's voltage.

I've tried a few things, but can't seem to get it to work I'm getting the error ValueError: Cannot convert argument type <type 'numpy.ndarray'> to rgba array. I'm not sure exactly how to convert what I need to convert, so if anybody could please offer some help, I'd be most appreciative.

My code is here:

fig = plt.figure()
from mpl_toolkits.mplot3d import Axes3D
cmhot = plt.cm.get_cmap("hot")
ax = fig.add_subplot(111, projection='3d',)
ax.scatter(x, y, z, v, s=50, c = cmhot)
plt.show()
askewchan
  • 45,161
  • 17
  • 118
  • 134
samanthapants
  • 77
  • 1
  • 1
  • 8
  • If it's not clear from unutbu answer, the _exact_ problem you are having is that the kwarg `c` is the values to be mapped and the kwarg `cmap` is the color map to map `c` with. http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.scatter – tacaswell Feb 24 '13 at 19:25

1 Answers1

9

ax.scatter can take a color parameter c which is a sequence (e.g. a list or an array) of scalars, and a cmap parameter to specify a color map. So to make the colors vary according to the magnitude of the voltages, you could define:

c = np.abs(v)

This makes positive and negative voltages have the same color. If instead you wished each color (positive or negative) to have its own color, you could just use c = v.


For example,

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
x, y, z, v = (np.random.random((4,100))-0.5)*15
c = np.abs(v)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
cmhot = plt.get_cmap("hot")
cax = ax.scatter(x, y, z, v, s=50, c=c, cmap=cmhot)

plt.show()

enter image description here

unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • Many thanks to both of you. I understand what I was doing wrong now. However, I have one more question. Fixing my code in the above way still gives me scatter points in blue (all the same shade). Additionally, copying and pasting the sample code given above by unutbu gives me the same plot as the one displayed above, but again only in blue. This would lead me to believe that perhaps I'm missing whatever package is necessary to use colour maps. Is there a package I'm missing, or something? I've been using the pythonxy distribution for a while now, and until today had no need of colour maps. – samanthapants Feb 24 '13 at 19:53
  • Hm, that's a curious problem. Sorry, I don't know the solution. I googled around but could not find any other questions/reports of this behavior. You might want to try posting a question here about how to fix this, or checking your .matplotlibrc configuration file (search for "blue" or "backend" or just browse to see if anything looks like a culprit), or -- if it is not too difficult -- reinstalling pythonxy. – unutbu Feb 24 '13 at 21:21
  • PS. I don't think you are *missing* a package, since `plt.get_cmap("hot")` does not raise an Exception. – unutbu Feb 24 '13 at 21:23
  • 1
    There is (was?) a bug in `matplotlib`, see this thread on SO: http://stackoverflow.com/questions/8971309/matplotlib-3d-scatter-color-lost-after-redraw – David Zwicker Feb 25 '13 at 11:50