我正在尝试使用matplotlib在3d散布动画中绘制粒子。我尝试修改官方的3D线图动画示例以实现此目的。但是,我的代码没有为这些点设置动画,而是立即渲染它们。我无法弄清楚问题是什么。任何帮助或提示将不胜感激。
MRE:
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as p3
import matplotlib.animation as animation
import numpy as np
def Gen_RandPrtcls():
n = 10
x = np.random.normal(size=(n,3))*5
# m = np.repeat(1. / n, n)
# Computing trajectory
data = [x]
nbr_iterations = 300
for iteration in range(nbr_iterations):
# data.append(data[-1] + GravAccel(data[-1], m))
data.append(data[-1]*1.01)
return data
def update_prtcls(num, dataPrtcls, parts):
for prtcl, data in zip(parts, dataPrtcls):
# NOTE: there is no .set_data() for 3 dim data...
prtcl.set_data(data[:num][:,0:1])
prtcl.set_3d_properties(data[:num][:,2])
return parts
# Attaching 3D axis to the figure
fig = plt.figure()
ax = p3.Axes3D(fig)
# Fifty parts of random 3-D parts
data = Gen_RandPrtcls()
# NOTE: Can't pass empty arrays into 3d version of plot()
parts = [ax.plot(dat[:,0], dat[:,1], dat[:,2], marker='.', linestyle="None")[0] for dat in data]
# Setting the axes properties
ax.set_xlim3d([-10.0, 10.0])
ax.set_xlabel('X')
ax.set_ylim3d([-10.0, 10.0])
ax.set_ylabel('Y')
ax.set_zlim3d([-10.0, 10.0])
ax.set_zlabel('Z')
ax.set_title('3D Test')
# Creating the Animation object
prtcl_ani = animation.FuncAnimation(fig, update_prtcls, 25, fargs=(data, parts),
interval=50, blit=False)
plt.show()
您以错误的顺序构造了data
。
def Gen_RandPrtcls(n_particles, n_iterations):
x = np.random.normal(size=(n_particles, 3))*5
# Computing trajectory
data = [x]
for iteration in range(n_iterations):
# data.append(data[-1] + GravAccel(data[-1], m))
data.append(data[-1]*1.01)
return data
data = Gen_RandPrtcls(n_particles=10, n_iterations=300)
data = np.array(data) # (n_iterations, n_particles, 3)
因此,在data
的第一维中是iterations
,第二个是不同的particles
,在第三个维中是spacial coordinates
。在当前更新中,您绘制了粒子0:num
的所有迭代。
我对您的代码做了一些小的更改。希望有帮助。
fig = plt.figure()
ax = p3.Axes3D(fig)
# Plot the first position for all particles
h = ax.plot(*data[0].T, marker='.', linestyle='None')[0]
# Equivalent to
# h = ax.plot(data[0, :, 0], data[0, :, 1], data[0, :, 2],
marker='.', linestyle='None')[0]
# Setting the axes properties
ax.set_xlim3d([-100.0, 100.0])
ax.set_xlabel('X')
ax.set_ylim3d([-100.0, 100.0])
ax.set_ylabel('Y')
ax.set_zlim3d([-100.0, 100.0])
ax.set_zlabel('Z')
ax.set_title('3D Test')
def update_particles(num):
# Plot the timesteps up to num for all particles
h.set_xdata(data[:num, :, 0].ravel())
h.set_ydata(data[:num, :, 1].ravel())
h.set_3d_properties(data[:num, :, 2].ravel())
return h
prtcl_ani = animation.FuncAnimation(fig, update_particles, frames=301,
interval=10)