Python 如何在matplotlib中制作火箭运动的动画?

Python 如何在matplotlib中制作火箭运动的动画?,python,animation,matplotlib,Python,Animation,Matplotlib,我有这个代码根据给定的数据计算某个火箭的位置、速度和加速度: import math import matplotlib.pyplot as plt import pylab as pl import numpy as np M = 30*10**3 m = 10*10**3 fi = 100 vr = 3*10**3 x = np.linspace (0, 324, 1296) def v(i): if i <= 225: y = vr*math.log((M

我有这个代码根据给定的数据计算某个火箭的位置、速度和加速度:

import math
import matplotlib.pyplot as plt
import pylab as pl
import numpy as np

M = 30*10**3
m = 10*10**3
fi = 100
vr = 3*10**3
x = np.linspace (0, 324, 1296)

def v(i):
    if i <= 225:
        y = vr*math.log((M+m)/(m+M - fi*i))
    elif i > 225:
        y = vr*math.log((M+m)/(m+M/4)) + vr*math.log((m)/(m - fi*(i - 225)))
    return y

def a(i):
    if i <= 225:
        y = fi*vr/(m+M - fi*i)
    elif i > 225:
        y = fi*vr/(m - fi*(i - 225))
    return y

def z(i):
    if i <= 225:
        y = vr/fi*(m+M-fi*i)*(math.log((1-fi*i/(m+M)))-1) + vr*(m+M)/fi
    elif i > 225:
        y = vr*(i-225)*math.log((m+M)/(m+M/4)) + z(225) + vr/fi*(m-fi*(i-225))*(math.log((1-fi*(i-225)/(m)))-1) + vr*m/fi
    return y


plt.figure(0)
ax1 = plt.subplot2grid((4,3), (0,1), colspan=2, rowspan=2)
plt.grid()
plt.plot (x, [v(i) for i in x], 'b--') 
plt.ylabel (r'Velocity [$\frac{m}{s}$]', fontsize = 16)
plt.xlabel ('Time [s]', fontsize = 16)
plt.title ('Velocity with respect to time', fontsize = 18)

ax2 = plt.subplot2grid((4,3), (0,0), colspan=1, rowspan=4)
plt.grid()
plt.plot (x, [z(i) for i in x], 'b--')
plt.ylabel (r'Position [m]', fontsize = 16)
plt.xlabel ('Time [s]', fontsize = 16)
plt.title ('Position with respect to time', fontsize = 18)

ax3 = plt.subplot2grid((4,3), (2,1), rowspan=2, colspan=2)
plt.grid()
plt.plot (x, [a(i) for i in x], 'b--') 
plt.xlabel ('Time [s]', fontsize = 16)
plt.ylabel (r'Acceleration [$\frac{m}{s^2}$]', fontsize = 16)
plt.title ('Acceleration with respect to time', fontsize = 18)

plt.suptitle ('Rocket behaviour', fontweight = 'bold', fontsize = 20)
plt.show()
导入数学
将matplotlib.pyplot作为plt导入
将pylab作为pl导入
将numpy作为np导入
M=30*10**3
m=10*10**3
fi=100
vr=3*10**3
x=np.linspace(03241296)
定义五(一):
如果我是:
y=vr*math.log((M+M)/(M+M/4))+vr*math.log((M)/(M-fi*(i-225)))
返回y
定义a(i):
如果我是:
y=fi*vr/(m-fi*(i-225))
返回y
定义z(i):
如果我是:
y=vr*(i-225)*数学日志((m+m)/(m+m/4))+z(225)+vr/fi*(m-fi*(i-225))*(数学日志((1-fi*(i-225)/(m))-1)+vr*m/fi
返回y
plt.图(0)
ax1=plt.subplot2grid((4,3)、(0,1),colspan=2,rowspan=2)
plt.grid()
plt.plot(x,[v(i)表示x中的i],'b--')
plt.ylabel(r'Velocity[$\frac{m}{s}$]',fontsize=16)
plt.xlabel('Time[s]',fontsize=16)
plt.title(“相对于时间的速度”,fontsize=18)
ax2=plt.subplot2grid((4,3)、(0,0),colspan=1,rowspan=4)
plt.grid()
plt.plot(x,[z(i)表示x中的i],'b--')
plt.ylabel(r'Position[m]',fontsize=16)
plt.xlabel('Time[s]',fontsize=16)
plt.title(‘相对于时间的位置’,fontsize=18)
ax3=plt.subplot2grid((4,3)、(2,1),rowspan=2,colspan=2)
plt.grid()
plt.plot(x,[a(i)表示x中的i],'b--')
plt.xlabel('Time[s]',fontsize=16)
plt.ylabel(r'Acceleration[$\frac{m}{s^2}$]',fontsize=16)
plt.title(“相对于时间的加速度”,fontsize=18)
plt.suptitle('Rocket behavior',fontwweight='bold',fontsize=20)
plt.show()

但是,与“相对于时间的位置”图不同,我想制作火箭在z方向(垂直向上)运动的动画。我怎么能这么做?我所有的尝试都失败了,所以我请求一些帮助。动画应为动画GIF格式。

这显示了一个动画:

输入数学

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation


def z(i):
    if i <= 225:
        y = (vr / fi * (m + M - fi * i) *
            (math.log((1 - fi * i / (m + M))) - 1)
            + vr * (m + M) / fi)
    elif i > 225:
        y = (vr * (i - 225) * math.log((m + M) / (m + M / 4)) + z(225) +
             vr / fi * (m - fi * (i - 225)) *
             (math.log((1 - fi * (i - 225) / (m))) - 1) + vr * m / fi)
    return y


class GrowingGraph(object):
    """The z and time axis are growing over time.
    """

    def __init__(self):
        self.x_data = []
        self.y_data = []
        self.fig, self.ax = plt.subplots()
        plt.ylabel(r'Position [m]', fontsize=16)
        plt.xlabel('Time [s]', fontsize=16)
        plt.title('Position with respect to time', fontsize=18)

    def run(self, data):
        # update the data
        x, y = data
        self.x_data.append(x)
        self.y_data.append(y)
        line, = self.ax.plot(self.x_data, self.y_data, color='blue')
        return line,

class FixedGraph(object):
    """z and time axis are fixed at maximum values.
    """

    def __init__(self, xmax, ymax):
        self.x_data = []
        self.y_data = []
        self.fig = plt.figure()
        self.ax = plt.axes(xlim=(0, xmax), ylim=(0, ymax))
        self.line, = self.ax.plot(self.x_data, self.y_data)
        self.line.set_data([], [])
        plt.ylabel(r'Position [m]', fontsize=16)
        plt.xlabel('Time [s]', fontsize=16)
        plt.title('Position with respect to time', fontsize=18)


    def run(self, data):
        # update the data
        x, y = data
        self.x_data.append(x)
        self.y_data.append(y)
        self.line.set_data(self.x_data, self.y_data)
        return self.line,

if __name__ == '__main__':

    M = 30 * 10 ** 3
    m = 10 * 10 ** 3
    fi = 100
    vr = 3 * 10 ** 3
    x = np.linspace(0, 324, 1296)

    data = zip(x, (z(i) for i in x))

    graph = FixedGraph(x[-1], z(x[-1]))
    ani = animation.FuncAnimation(graph.fig, graph.run, frames=data,
                                  interval=200, repeat=False)

    # Comment out this line if you don't want see the animation.
    plt.show()

    # save as gif
    ani.save('rocket.gif', writer='imagemagick', fps=4)

    # save as mp4
    ani.save('rocket.mp4', writer='ffmpeg', fps=15)
导入matplotlib.pyplot作为plt
将numpy作为np导入
将matplotlib.animation导入为动画
定义z(i):
如果我是:
y=(vr*(i-225)*数学日志((m+m)/(m+m/4))+z(225)+
vr/fi*(m-fi*(i-225))*
(数学日志((1-fi*(i-225)/(m))-1)+vr*m/fi)
返回y
类增长图(对象):
“”“z轴和时间轴随时间而增长。
"""
定义初始化(自):
self.x_数据=[]
self.y_数据=[]
self.fig,self.ax=plt.subplot()
plt.ylabel(r'Position[m]',fontsize=16)
plt.xlabel('Time[s]',fontsize=16)
打印标题(“相对于时间的位置”,字体大小=18)
def运行(自身、数据):
#更新数据
x、 y=数据
self.x_data.append(x)
self.y_data.append(y)
行,=self.ax.plot(self.x_数据,self.y_数据,color='blue')
回程线,
类FixedGraph(对象):
“”“z和时间轴固定为最大值。
"""
定义初始化(self,xmax,ymax):
self.x_数据=[]
self.y_数据=[]
self.fig=plt.figure()
self.ax=plt.axs(xlim=(0,xmax),ylim=(0,ymax))
self.line,=self.ax.plot(self.x_数据,self.y_数据)
self.line.set_数据([],[])
plt.ylabel(r'Position[m]',fontsize=16)
plt.xlabel('Time[s]',fontsize=16)
打印标题(“相对于时间的位置”,字体大小=18)
def运行(自身、数据):
#更新数据
x、 y=数据
self.x_data.append(x)
self.y_data.append(y)
self.line.set_数据(self.x_数据、self.y_数据)
返回自助线路,
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
M=30*10**3
m=10*10**3
fi=100
vr=3*10**3
x=np.linspace(03241296)
数据=zip(x,(z(i)表示x中的i))
图=固定图(x[-1],z(x[-1]))
ani=animation.FuncAnimation(graph.fig,graph.run,frames=数据,
间隔=200,重复=假)
#如果不想看到动画,请注释掉这一行。
plt.show()
#另存为gif
ani.save('rocket.gif',writer='imagemagick',fps=4)
#另存为mp4
ani.save('rocket.mp4',writer='ffmpeg',fps=15)
FuncAnimation()
需要使用
figure
实例调用,
更新绘图和数据的可调用函数。该代码具有详细信息。

此代码非常有效,但我在导出动画时遇到一个小问题。出现此错误:AttributeError:“NoneType”没有属性“tk”。如何解决这个问题?什么是“出口”?保存为GIF?你能展示更多的回溯吗?这样我就可以看到导致问题的代码行了。看起来Tkinter不起作用。尝试使用不同的后端。例如,在开头添加以下两行:
import matplotlib
matplotlib.use(“Qt4Agg”)
在从matplotlib导入所有其他内容之前。您可能需要安装PySide或PyQt。您也可以尝试
WXAgg
GTKAgg
。我使用Tkinter进行了尝试,得到了相同的错误。如果我在
FuncAnimation
中设置了
interval=200
(请参阅更新的答案),它按预期工作。因此,我尝试了您的所有建议,包括将间隔增加到200,但现在我得到了一个稍微不同的错误。以下是完整回溯的图像: