3d animated scatter plot

Hi

I’m trying to plot the trajectory of a particle in 3d using mplot3d. I tried to follow the example of an animated 3d plot on the matplotlib website but I’m having trouble with the updating of the data point being plotted at each frame. Does anyone know how to do this?

So far I have:

import numpy as np

import matplotlib.pyplot as plt

from mpl_toolkits.mplot3d.axes3d import Axes3D

from matplotlib.animation import FuncAnimation

def update_plot(num, data, sc):

sc.set_array(data[num])

return sc

def main():

numframes = 2

data = np.random.rand(10, 3)# a (time, position) array

fig = plt.figure()

ax = fig.add_subplot(111, projection=‘3d’)

ix, iy, iz = data[0]

sc = ax.scatter(ix, iy, iz, c=‘k’)

ani = FuncAnimation(fig, update_plot, frames=numframes,

fargs=(data,sc))

plt.show()

if name == ‘main’:

main()

This just changes the color of the initial marker. I also tried to use sc.set_3d_properties but it is not clear to me what the arguments should be here, I kept getting an error… If anyone has done this before I’d love to see an example.

Thanks,

Andrew

Andrew,

For scatter objects (which are PatchCollection), the get/set_data() refers to the scalar mappable part of things, which is why the color kept changing. It does not seem to be an easy way to adjust the position data for a Patch3DCollection (or a Line3DCollection for that matter…). I would suggest filing a feature request about that on github. In coming up with an example for your use-case, I have come across a couple of minor bugs in mplot3d that I am going to need to resolve as well. In the meantime, I think the following version of the code:

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

def update_plot(num, data, sc):
print sc._offsets3d

sc._offsets3d = data[num]
return sc

def main():
numframes = 10
data = np.random.rand(numframes, 3, 1)# a (time, position) array

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

ix, iy, iz = data[0]
sc = ax.scatter(ix, iy, iz, c='k')
ani = FuncAnimation(fig, update_plot, frames=numframes,
        fargs=(data,sc))
plt.show()

if name == ‘main’:

main()

Essentially, there is no nice way to set the 3d position data, and the easiest way is to just go to the internal _offsets3d variable. Second, there seems to be an issue with array/scalar data in Patch3DCollection that I had to make the random number generation be 3D, rather than 2D as you originally had it.

Cheers!
Ben Root

···

On Sun, Nov 11, 2012 at 1:42 PM, Andrew Dawson <dawson@…4239…> wrote:

Hi

I’m trying to plot the trajectory of a particle in 3d using mplot3d. I tried to follow the example of an animated 3d plot on the matplotlib website but I’m having trouble with the updating of the data point being plotted at each frame. Does anyone know how to do this?

So far I have:

import numpy as np

import matplotlib.pyplot as plt

from mpl_toolkits.mplot3d.axes3d import Axes3D

from matplotlib.animation import FuncAnimation

def update_plot(num, data, sc):

sc.set_array(data[num])

return sc

def main():

numframes = 2

data = np.random.rand(10, 3)# a (time, position) array

fig = plt.figure()

ax = fig.add_subplot(111, projection=‘3d’)

ix, iy, iz = data[0]

sc = ax.scatter(ix, iy, iz, c=‘k’)

ani = FuncAnimation(fig, update_plot, frames=numframes,

fargs=(data,sc))

plt.show()

if name == ‘main’:

main()

This just changes the color of the initial marker. I also tried to use sc.set_3d_properties but it is not clear to me what the arguments should be here, I kept getting an error… If anyone has done this before I’d love to see an example.

Thanks,

Andrew