如何在Python上设置3D图形的动画

如何在Python上设置3D图形的动画,python,numpy,matplotlib,Python,Numpy,Matplotlib,我正在寻找动画我的图形(如下),我不确定这是否是正确的代码动画3个不同的绘图在同一个图形在三维。我还想知道我是否必须分别为所有三个绘图设置动画,或者是否可以在一个函数下设置动画。如果有人能给我任何建议,如何修改这段代码,使其能够满足这个问题,我将不胜感激。如果您需要代码的其他部分来帮助我,请在下面进行注释,我将尽快发布这些部分 def func(length, dims=2) : lineData = np.empty((dims, length)) lineData[:,0]

我正在寻找动画我的图形(如下),我不确定这是否是正确的代码动画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)
回溯(最近一次呼叫上次)
在里面
20轴=plt.轴(投影='3d')
21
--->22数据=[func(500500)表示范围(50)内的索引]
23
对于数据中的数据,24行=[ax.绘图(x1[:,0],x1[:,1],x1[:,2])[0]
英寸(.0)
20轴=plt.轴(投影='3d')
21
--->22数据=[func(500500)表示范围(50)内的索引]
23
对于数据中的数据,24行=[ax.绘图(x1[:,0],x1[:,1],x1[:,2])[0]
在func中(长度,dims)
2.
3 lineData=np.空((dims,长度))
---->4 lineData[:,0],lineData[:,1],lineData[:,2]=x1,x2,x3
5对于范围内的索引(1,长度):
6.
ValueError:无法将输入数组从形状(50,3)广播到形状(500)

您可能是从随机游走代码开始工作的。 这是一个很好的例子,但要理解他们在做什么并不总是容易的

该示例有一个函数
Gen_RandLine
,他们调用该函数50次,每次行走一次。你只有3次散步,所以你应该只叫它3次。此外,x1、x2、x3中已经有了完整的轨迹,而它们从头开始生成轨迹。您的情况有所不同,因为您的轨迹相互依赖,而在本例中,轨迹是随机且独立的

无论如何,我调用了函数
generate\u lines\u from_x123
,以便更好地传达它的功能

我还为x1、x2、x3创建了一些测试数据,因为我没有您的模拟功能。只有3个易于编程的螺旋

在函数中,
updatelines
数据行
包含所有数据,而
仅包含在每个步骤中实际绘制的行

以下是您的代码的改编版本,其功能似乎与预期相符:

将numpy导入为np
将matplotlib.pyplot作为plt导入
将matplotlib.animation导入为动画
从mpl_toolkits.mplot3d导入Axes3D
N=500#步数
x1=np.零((N,3))
x2=np.零((N,3))
x3=np.零((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从_x123生成_线(长度,x1,dims=3):
lineData=np.空((dims,长度))
lineData[:,0]=x1[0]
对于范围(1,长度)中的索引:
lineData[:,index]=x1[索引]
返回行数据
def更新行(num、数据行、行):
对于行,zip中的数据(行、数据行):
line.set_数据(数据[0:2,:num])
line.set_3d_属性(数据[2,:num])
回程线
图=plt.图(图尺寸=(15,15))
ax=图添加_子图(111,投影='3d')
ax.set_标题(“3体问题”)
do_animation=True
如果不做动画:
数据=[为x-in(x1,x2,x3)从_x123(N,x,3)生成_线_]
直线=[x[:,0],x[:,1],x[:,2])[0]表示x in(x1,x2,x3)]
line_ani=animation.FuncAnimation(图,更新线,N,fargs=(数据,行),
间隔=100,blit=False)
其他:
#只要画出3条曲线
坐标图(x1[:,0],x1[:,1],x1[:,2],颜色='b')
ax.绘图(x2[:,0],x2[:,1],x2[:,2],颜色='m')
ax.plot(x3[:,0],x3[:,1],x3[:,2],颜色='g')
最大散射(x1[-1,0],x1[-1,1],x1[-1,2],颜色='b',标记='o',s=30,标签='Mass 1')
最大散射(x2[-1,0],x2[-1,1],x2[-1,2],颜色为'm',标记为'o',s=90,标签为'Mass 2')
最大散射(x3[-1,0],x3[-1,1],x3[-1,2],颜色为“g”,标记为“o”,s=60,标签为“质量3”)
ax.图例()
plt.show()

您应该在一个更新功能中更新所有的
艺术家(线条、散点等)。我不确定我是否理解你的问题。你的代码不工作吗?用什么方法?它不起作用。如果我运行代码,会弹出一个错误,指向data=[func(500500)for index in range(50)]行,表示“无法将输入数组从形状(500,3)广播到形状(500)”。我不确定这意味着什么,也不确定如何修复它。这是我第一次做动画,总是把完整的错误消息(从单词“Traceback”开始)作为文本(而不是截图)进行讨论(不是评论)。还有其他有用的信息。此错误意味着您试图将数据放置在空数组中,但它不适合,因为形状不正确。您需要检查
x1
x2
x3
的内容-它们看起来像是在
func
范围之外定义的外部变量当我打印x1、x2和x3时,它们的长度为50,每个索引都有一个包含3个数字的数组。我不知道如何修改代码来设置这样的数据动画。