1

I have a similar problem to this one: Animate a python pyplot by moving a point plotted via scatter. The given values are positions (q) with corresponding velocities (v). Now I want to animate the shift in position over time for each point. My attempt

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


fig = plt.figure()
ax = p3.Axes3D(fig)

q = [[-4.32, -2.17, -2.25, 4.72, 2.97, 1.74],
     [ 2.45, 9.73,  7.45,4.01,3.42,  1.80],[-1.40, -1.76, -3.08,-9.94,-3.13,-1.13]]
v = [[ 0.0068,0.024, -0.014,-0.013, -0.0068,-0.04],[ 0.012,
      0.056, -0.022,0.016,  0.0045, 0.039],
     [-0.0045,  0.031,  0.077,0.0016, -0.015,-0.00012]]

t=np.arange(0, 1000, 2)
x=q[0]
y=q[1]
z=q[2]
s=v[0]
u=v[1]
w=v[2]


points, = ax.plot(x, y, z, '*')

def update_points(t, x, y, z, points):
    point = []
    for i in range(0,len(x)-1,1):
        points.set_data(np.array([x[i]+s[i]*t*5, y[i]+u[i]*t*5]))
        points.set_3d_properties(z[i]+w[i]*t*5, 'z')
    return point

ani=animation.FuncAnimation(fig, update_points, 10, fargs=(x, y, z, points))

plt.show()

does not work properly. The first image of the animation shows all points, but afterward, only the movement of the last point is simulated. The error happens in the defined update_points function because it seems like only the values for the last I are stored. Does anybody know how I have to change the code that all points are moving simultaneously?

2 Answers 2

4

Your problem is that you are only passing one set of coordinates to set_data()/set_3d_properties, and therefore only one point remains. You need to update all the coordinates of all your points, and then update points with those arrays.

I could not figure out exactly how you were doing your math in the update function, so here's an example using random fluctuations:

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


fig = plt.figure()
ax = p3.Axes3D(fig)

q = [[-4.32, -2.17, -2.25, 4.72, 2.97, 1.74],
     [ 2.45, 9.73,  7.45,4.01,3.42,  1.80],[-1.40, -1.76, -3.08,-9.94,-3.13,-1.13]]
v = [[ 0.0068,0.024, -0.014,-0.013, -0.0068,-0.04],[ 0.012,
      0.056, -0.022,0.016,  0.0045, 0.039],
     [-0.0045,  0.031,  0.077,0.0016, -0.015,-0.00012]]

x=np.array(q[0])
y=np.array(q[1])
z=np.array(q[2])
s=np.array(v[0])
u=np.array(v[1])
w=np.array(v[2])


points, = ax.plot(x, y, z, '*')
txt = fig.suptitle('')

def update_points(num, x, y, z, points):
    txt.set_text('num={:d}'.format(num)) # for debug purposes

    # calculate the new sets of coordinates here. The resulting arrays should have the same shape
    # as the original x,y,z
    new_x = x+np.random.normal(1,0.1, size=(len(x),))
    new_y = y+np.random.normal(1,0.1, size=(len(y),))
    new_z = z+np.random.normal(1,0.1, size=(len(z),))

    # update properties
    points.set_data(new_x,new_y)
    points.set_3d_properties(new_z, 'z')

    # return modified artists
    return points,txt

ani=animation.FuncAnimation(fig, update_points, frames=10, fargs=(x, y, z, points))

plt.show()

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

1

Thank you very much! It works now

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


fig = plt.figure()
ax = p3.Axes3D(fig)

q = [[-4.32, -2.17, -2.25, 4.72, 2.97, 1.74],
     [ 2.45, 9.73,  7.45,4.01,3.42,  1.80],[-1.40, -1.76, -3.08,-9.94,-3.13,-1.13]]
v = [[ 0.0068,0.024, -0.014,-0.013, -0.0068,-0.04],[ 0.012,
      0.056, -0.022,0.016,  0.0045, 0.039],
     [-0.0045,  0.031,  0.077,0.0016, -0.015,-0.00012]]

x=np.array(q[0])
y=np.array(q[1])
z=np.array(q[2])
s=np.array(v[0])
u=np.array(v[1])
w=np.array(v[2])

points, = ax.plot(x, y, z, '*')
txt = fig.suptitle('')

def update_points(t, x, y, z, points):
    txt.set_text('num={:d}'.format(t))

    new_x = x + s * t
    new_y = y + u * t
    new_z = z + w * t
    print('t:', t)

    # update properties
    points.set_data(new_x,new_y)
    points.set_3d_properties(new_z, 'z')

    # return modified artists
    return points,txt

ani=animation.FuncAnimation(fig, update_points, frames=15, fargs=(x, y, z, points))

ax.set_xlabel("x [pc]")
ax.set_ylabel("y [pc]")
ax.set_zlabel('z [pc]')
plt.show()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.