scipy 动画MatPlotLib帧更新错误

xv8emn3q  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(86)

我试图制作一个动画,描绘猎鹰9号由于发动机故障而造成的理论上的灾难轨迹。然而,我的代码如下所示:

import numpy as np
from scipy.integrate import solve_ivp

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

def rocket(t, state):
   # state = [x, y, phi, vx, vy, dphi/dt]
   # dstate = [vx, vy, dphi/dt, ax, ay, ddphi/dt2]

   dstate = np.zeros(6)
   dstate[0:3] = state[3:]
      
   if t > 60:
      dstate[3] = 898.94 * 1000 * 7 * np.cos(state[2]) / 550000
      dstate[4] = (898.94 * 1000 * 7 * np.sin(state[2]) / 550000) - 9.81
      dstate[5] = - 0.01109404141387943 
      # dstate[5] = (2 * 1.5 *  np.cos(np.pi / 8) * 898.94 * 1000) / ((550000 * 70 ** 2) / 12)
   else:
      dstate[3] = 898.94 * 1000 * 9 * np.cos(state[2]) / 550000
      dstate[4] = (898.94 * 1000 * 9 * np.sin(state[2]) / 550000) - 9.81
      dstate[5] = 0

   return dstate

sol = solve_ivp(rocket, [0, 150], [0, 0, np.pi / 2, 0, 0, 0], t_eval = np.linspace(0, 150, 151))
plt.plot(sol.y[0] / 1000, sol.y[1] / 1000)

'''
print(len(sol.y[0]))
print()
print(len(np.linspace(0, 150, 151)))
'''

fig, ax = plt.subplots()
x_pos, y_pos = [], []
ln, = ax.plot([], [])

def init():
    ax.set_xlim(-5, 10)
    ax.set_ylim(0, 25)

    ax.set_xlabel("x Position (km)")
    ax.set_ylabel("y Position (km)")
    ax.set_title("Falcon 9 Asymmetric Engine Failure Trajectory")

    return ln,

def update(frame):
    x_pos.append(sol.y[0][frame])
    y_pos.append(sol.y[1][frame])
    ln.set_data(x_pos, y_pos)
    return ln,

ani = FuncAnimation(fig, update, frames = np.linspace(0, 150, 151), init_func = init, blit = True)

plt.show()

会产生以下终端错误:

jacobivanov@Jacob-Ivanovs-MacBook-Air Lab 6 % /opt/homebrew/bin/python3 "/Users/jacobivanov/Desktop
/Falcon 9 Disaster Trajectory.py"
Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.10/site-packages/matplotlib/backend_bases.py", line 1193, in _on_timer
    ret = func(*args, **kwargs)
  File "/opt/homebrew/lib/python3.10/site-packages/matplotlib/animation.py", line 1404, in _step
    still_going = super()._step(*args)
  File "/opt/homebrew/lib/python3.10/site-packages/matplotlib/animation.py", line 1097, in _step
    self._draw_next_frame(framedata, self._blit)
  File "/opt/homebrew/lib/python3.10/site-packages/matplotlib/animation.py", line 1116, in _draw_next_frame
    self._draw_frame(framedata)
  File "/opt/homebrew/lib/python3.10/site-packages/matplotlib/animation.py", line 1743, in _draw_frame
    self._drawn_artists = self._func(framedata, *self._args)
  File "/Users/jacobivanov/Desktop/Falcon 9 Disaster Trajectory.py", line 50, in update

值得注意的是,这个区块在终端中可能重复了151次。问题似乎在于我们如何在更新过程中引用列表,因为下面的替换导致了同样的bug:

a = np.linspace(0, 150, 151)
b = np.linspace(0, 150, 151)
def update(frame):
   '''
   x_pos.append(sol.y[0][frame])
   y_pos.append(sol.y[1][frame])
   '''
   x_pos.append(a[frame])
   y_pos.append(b[frame])

   ln.set_data(x_pos, y_pos)
   return ln,

ani = FuncAnimation(fig, update, frames = np.linspace(0, 150, 151), init_func = init, blit = True)

plt.show()

帧的长度和解出的位置是相同的索引长度,所以没有不匹配的地方。否则,我不知道我的错误在哪里。

ymdaylpp

ymdaylpp1#

当你设置“frames = np.linspace(0,150,151)"时,它会设置一个数组[0.0,1.0,2.0...,150.0]。索引只能是整数,不能是浮点数,因此,当你想执行“a[frame]”,即a[1.0]时,它会抛出错误。只需在索引中添加一个int()函数。

相关问题