具有多个移动点的动画3d python绘图

时间:2018-08-01 11:35:51

标签: python matplotlib

我有与此类似的问题: 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的值。有人知道我必须更改所有点同时移动的代码吗?

2 个答案:

答案 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()

enter image description here

答案 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()