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

标签 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

最佳答案

您可能是从 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()

关于python - 如何在 Python 上制作 3D 图形动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59095592/

相关文章:

python - 向量化嵌套循环

python - 将 numpy 数组绘制到 QWidget 中时出现问题

python - Matplotlib 箱线图 : what algorithm is used to calculate range and identify outliers?

python - Matplotlib - Tcl_AsyncDelete : async handler deleted by the wrong thread?

Python设计题

python - 在Raspberry Pi和Python上流式传输YouTube播放列表

python - 改善Elasticsearch性能

Python 3.1 网格模拟题

python - 给定一些数据,我如何预测 matplotlib 将在何处绘制刻度?

python - 使用 NumPy 从矩阵中获取最小/最大 n 值和索引的有效方法