0

I'm creating a 3D scatter plot with multiple sets of data and using a colormap for the whole figure. The code looks like this:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

for R in [range(0,10), range(5,15), range(10,20)]:
  data = [np.array(R), np.array(range(10)), np.array(range(10))]
  AX = ax.scatter(*data, c=data[0], vmin=0, vmax=20, cmap=plt.cm.jet)
  def forceUpdate(event): AX.changed()
  fig.canvas.mpl_connect('draw_event', forceUpdate)

plt.colorbar(AX)

This works fine but as soon as I save it or rotate the plot, the colors on the first and second scatters turn blue.

3D scatter loses color map info on all but the last data set.

The force update is working by keeping the colors but only on the last scatter plot drawn. I tried making a loop that updates all the scatter plots but I get the same result as above:

AX = []
for R in [range(0,10), range(5,15), range(10,20)]:
  data = [np.array(R), np.array(range(10)), np.array(range(10))]
  AX.append(ax.scatter(*data, c=data[0], vmin=0, vmax=20, cmap=plt.cm.jet))
for i in AX:
  def forceUpdate(event): i.changed()
  fig.canvas.mpl_connect('draw_event', forceUpdate)

Any idea how I can make sure all scatters are being updated so the colors don't disappear?

Thanks!

Joe Flip
  • 1,076
  • 4
  • 21
  • 37

1 Answers1

0

Having modified your code so that it does anything:

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from mpl_toolkits.mplot3d import Axes3D
>>> AX = \[\]
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111, projection='3d')
>>> for R in \[range(0,10), range(5,15), range(10,20)\]:
...   data = \[np.array(R), np.array(range(10)), np.array(range(10))\]
...   AX = ax.scatter(*data, c=data\[0\], vmin=0, vmax=20, cmap=plt.cm.jet)
...   def forceUpdate(event): AX.changed()
...   fig.canvas.mpl_connect('draw_event', forceUpdate)
... 
9
10
11
>>> plt.colorbar(AX)
<matplotlib.colorbar.Colorbar instance at 0x36265a8>
>>> plt.show()

then I get: Result of save after rotate

So the above code is working. If your existing code isn't then I suggest that you try the exact code above and if that doesn't work look into the versions of code that you are using if it does work then you will have to investigate the differences between it and your actual code, (rather than your example code).

Steve Barnes
  • 27,618
  • 6
  • 63
  • 73
  • What did you change? All I see is that you put the `plt.colorbar(AX)` inside the loop. All this does is draw three color bars without fixing the problem of the scatter points turning blue when the figure is rotated or saved. – Joe Flip Aug 14 '13 at 18:38
  • When I started with the code you have posted as the first example it wouldn't run for a couple of reasons, a) no `import numpy as np` and b) AX was not in scope for `plt.colorbar(AX)` so I moved it into scope and got 3. If as I expect you have `AX=[]` missing from the example at the outer scope and possibly some others you will get the shallow copy problem - i.e. when each is plotted it has one set of mappings but since there is only one actual AX on the redraw they end up the same. – Steve Barnes Aug 14 '13 at 20:02
  • Sure, that was just an oversight when I copied it into the browser. Of course I had those things in there since I was able to generate the plot above. The problem is that the color mapping of the points disappears when the plot is rotated or saved. Any idea why that might be happening? – Joe Flip Aug 15 '13 at 01:57
  • 1
    Which versions of python, numpy, mathplotlib and mplot3d are you using mine are: Python 2.7.4, numpy 1.7.1, mathplotlib 1.2.1 and mplot3d not sure but recent. – Steve Barnes Aug 15 '13 at 05:28
  • Ah... I have Python v2.7.3, Numpy v1.6.1 and Matplotlib v1.1.0. I'll update them all and try again! – Joe Flip Aug 15 '13 at 13:32
  • 1
    I just updated Matplotlib to 1.2.1 and it works! Thanks @SteveBarnes! – Joe Flip Aug 15 '13 at 13:59