我正在为我的图形设置动画(如下图),但我不确定这是否是为同一张3D图形绘制3个不同图形的正确代码。我也想知道是否必须分别对所有三个图进行动画处理,或者是否可以在一个功能下进行动画处理。如果有人可以给我有关如何修改此代码的任何建议,以便它可以满足此问题,我将不胜感激。如果您需要其他代码部分来帮助我解决此问题,请在下面注释掉,我将尽快发布这些部分。
def func(length, dims=2) :
lineData = np.empty((dims, length))
lineData[:,0],lineData[:,1],lineData[:,2] = x1,x2,x3
for index in range(1, length) :
step = ((x1 - 0.5) * 0.1)
lineData[:, index] = lineData[:, index-1] + step
return lineData
def updatelines(num, dataLines, lines) :
for line, data in zip(lines, dataLines) :
line.set_data(data[0:2, :num])
line.set_3d_properties(data[2,:num])
return lines
fig = plt.figure(figsize = (15,15))
ax = fig.add_subplot(111,projection = '3d')
data = [func(500, 500) for index in range(50)]
lines = [ax.plot(x1[:,0], x1[:,1], x1[:,2])[0] for dat in data]
ax.set_title('3 Body Problem')
line_ani = animation.FuncAnimation(fig, updatelines, 25, fargs=(data, lines),
interval=100, blit=False)
ax.plot(x1[:,0],x1[:,1],x1[:,2],color = 'b')
ax.plot(x2[:,0],x2[:,1],x2[:,2],color = 'm')
ax.plot(x3[:,0],x3[:,1],x3[:,2],color = 'g')
ax.scatter(x1[-1,0],x1[-1,1],x1[-1,2],color = 'b', marker = 'o', s=30, label = 'Mass 1')
ax.scatter(x2[-1,0],x2[-1,1],x2[-1,2],color = 'm', marker = 'o',s=90, label = 'Mass 2')
ax.scatter(x3[-1,0],x3[-1,1],x3[-1,2],color = 'g', marker = 'o',s=60, label = 'Mass 3')
ax.legend()
plt.show()
错误消息:
Traceback (most recent call last)
<ipython-input-47-3faf8380342f> in <module>
20 ax = plt.axes(projection = '3d')
21
---> 22 data = [func(500, 500) for index in range(50)]
23
24 lines = [ax.plot(x1[:,0], x1[:,1], x1[:,2])[0] for dat in data]
<ipython-input-47-3faf8380342f> in <listcomp>(.0)
20 ax = plt.axes(projection = '3d')
21
---> 22 data = [func(500, 500) for index in range(50)]
23
24 lines = [ax.plot(x1[:,0], x1[:,1], x1[:,2])[0] for dat in data]
<ipython-input-47-3faf8380342f> in func(length, dims)
2
3 lineData = np.empty((dims, length))
----> 4 lineData[:,0],lineData[:,1],lineData[:,2] = x1,x2,x3
5 for index in range(1, length) :
6
ValueError: could not broadcast input array from shape (50,3) into shape (500)
答案 0 :(得分:1)
可能您是从this example处的随机游走代码开始工作的。 这是一个很好的例子,但要了解他们在做什么并不总是那么容易。
该示例具有一个函数Gen_RandLine
,该函数每次调用50次,每次调用一次。您只有3条步行路线,因此您只能拨打3次。同样,您已经具有x1,x2,x3的完整轨迹,而它们是从头开始生成轨迹的。您的情况有所不同,因为您的轨迹相互依赖,而在此示例中,轨迹是随机且独立的。
无论如何,我调用了该函数generate_lines_from_x123
以更好地传达其功能。
我还为x1,x2,x3创建了一些测试数据,因为我没有仿真功能。只需3个易于编程的螺旋线。
在函数updatelines
中dataLines
包含所有数据,而lines
仅包含在每个步骤中实际绘制的线。
这是您的代码的改编版,它似乎可以按预期运行:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from mpl_toolkits.mplot3d import Axes3D
N = 500 # number of steps
x1 = np.zeros((N, 3))
x2 = np.zeros((N, 3))
x3 = np.zeros((N, 3))
t = np.linspace(0, 20, N)
x1[:,0] = np.sin(t)
x1[:,1] = np.cos(t)
x1[:,2] = t
x2[:,0] = np.sin(t+1)
x2[:,1] = np.cos(t+1)
x2[:,2] = t
x3[:,0] = np.sin(t+2)
x3[:,1] = np.cos(t+2)
x3[:,2] = t
def generate_lines_from_x123(length, x1, dims=3):
lineData = np.empty((dims, length))
lineData[:,0] = x1[0]
for index in range(1, length) :
lineData[:, index] = x1[index]
return lineData
def updatelines(num, dataLines, lines) :
for line, data in zip(lines, dataLines) :
line.set_data(data[0:2, :num])
line.set_3d_properties(data[2,:num])
return lines
fig = plt.figure(figsize = (15,15))
ax = fig.add_subplot(111, projection = '3d')
ax.set_title('3 Body Problem')
do_animation = True
if do_animation:
data = [generate_lines_from_x123(N, x, 3) for x in (x1, x2, x3)]
lines = [ax.plot(x[:,0], x[:,1], x[:,2])[0] for x in (x1, x2, x3)]
line_ani = animation.FuncAnimation(fig, updatelines, N, fargs=(data, lines),
interval=100, blit=False)
else:
# just plot the 3 curves
ax.plot(x1[:,0],x1[:,1],x1[:,2],color = 'b')
ax.plot(x2[:,0],x2[:,1],x2[:,2],color = 'm')
ax.plot(x3[:,0],x3[:,1],x3[:,2],color = 'g')
ax.scatter(x1[-1,0],x1[-1,1],x1[-1,2],color = 'b', marker = 'o', s=30, label = 'Mass 1')
ax.scatter(x2[-1,0],x2[-1,1],x2[-1,2],color = 'm', marker = 'o',s=90, label = 'Mass 2')
ax.scatter(x3[-1,0],x3[-1,1],x3[-1,2],color = 'g', marker = 'o',s=60, label = 'Mass 3')
ax.legend()
plt.show()