首页 > 解决方案 > Python动画奇怪的行为

问题描述

我正在制作发射弹丸的动画并遇到一些我不理解的奇怪行为。我正在绘制一个点的动画,表示对象,并为路径设置动画,以便轨迹显示在对象后面。但是,当我按照我认为我应该这样做的方式执行此操作时,该点会显示在轨迹之前一步,并且轨迹最终会比完成少一分。我可以通过增加轨迹的索引号来解决这个问题,但是看起来索引最后应该超出范围。我真的很困惑,可以使用一些帮助来理解发生了什么。

我正在使用 Jupyter 笔记本,并在下面提供了一个最低限度的工作示例。我目前在我的 linspace 命令中只使用了 10 个点,并且已经大大减慢了动画的速度,这样你就可以看到发生了什么。如果我在动画函数中使用该命令line1.set_data(x[0:frames+1], y[0:frames+1])point1.set_data(x[frames], y[frames])那么一切看起来都很好。但这似乎不应该工作!

我错过了什么?

%matplotlib notebook

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

# Global constants
g = 9.8  # gravitational field strength in m/s^2
v0 = 40.0  # initial speed in m/s
theta = 30.0  # Launch angle in degrees

# determine trajectory
theta_rad = np.pi*theta/180
t = np.linspace(0, 2*v0*np.sin(theta_rad)/g, 10)
x = v0*np.cos(theta_rad)*t
y = v0*t*np.sin(theta_rad) - g*t**2/2

# Plot the results
fig1 = plt.figure(figsize=(6,4))
ax1 = fig1.add_subplot(111)
line1, = ax1.plot(x[0:1], y[0:1], 'b-', label='no drag')
point1, = ax1.plot(x[0], y[0], 'bo', ms=3)

ax1.set_xlim(0, 170)
ax1.set_ylim(0, 50)
plt.show()

# Animation update function
def animate(frames):
    line1.set_data(x[0:frames], y[0:frames])
    point1.set_data(x[frames], y[frames])
    return

ani = animation.FuncAnimation(fig1, animate, frames=len(t), interval=1000, blit=True, repeat=False)
plt.show()

标签: pythonmatplotlibanimation

解决方案


在 python 中,语法x[0:frames]定义了从 0 到 Exclusive 的frames 范围

所以,考虑循环:

  • 在第 0 次迭代中,您正在更新点,x[0], y[0]而线图为空:x[0:0], y[0:0]是空集;
  • 在第 1 次迭代中,您已经更新了点,x[1], y[1]而线只有一对坐标:x[0:1], y[0:1],不足以形成一条线;
  • 在迭代 2 中,该点位于其第三个位置x[2], y[2],但线图滞后,因为x[0:2], y[0:2]包含足够的两个点的坐标,即第一个点和第二个点,足以仅形成第一段而不是到达该点所需的第二段。

推荐阅读