如何在Python上制作3D图形动画

时间:2019-11-28 20:10:16

标签: python numpy matplotlib

我正在为我的图形设置动画(如下图),但我不确定这是否是为同一张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)

enter image description here

1 个答案:

答案 0 :(得分:1)

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

该示例具有一个函数Gen_RandLine,该函数每次调用50次,每次调用一次。您只有3条步行路线,因此您只能拨打3次。同样,您已经具有x1,x2,x3的完整轨迹,而它们是从头开始生成轨迹的。您的情况有所不同,因为您的轨迹相互依赖,而在此示例中,轨迹是随机且独立的。

无论如何,我调用了该函数generate_lines_from_x123以更好地传达其功能。

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

在函数updatelinesdataLines包含所有数据,而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()