我有与此类似的问题: Animate a python pyplot by moving a point plotted via scatter。 给定的值是具有相应速度(v)的位置(q)。现在,我想为每个点设置位置随时间变化的动画。我的尝试
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()
无法正常工作。动画的第一个图像显示所有点,但是之后,仅模拟最后一个点的运动。该错误发生在已定义的update_points函数中,因为似乎只存储了最后一个I的值。有人知道我必须更改所有点同时移动的代码吗?
答案 0 :(得分:1)
您的问题是,您仅将一组坐标传递到set_data()
/ set_3d_properties
,因此仅剩下一个点。您需要更新所有点的所有坐标,然后使用这些数组更新points
。
我无法确切地知道您在update函数中如何进行数学运算,因此这是一个使用随机波动的示例:
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()
答案 1 :(得分:0)
非常感谢!现在可以使用
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()