Python 升级到matplotlib 3.3.2时动画停止工作
我有一段Python代码,用于一个最近停止工作的动画可视化。我已跟踪该问题,从Python 升级到matplotlib 3.3.2时动画停止工作,python,matplotlib,animation,Python,Matplotlib,Animation,我有一段Python代码,用于一个最近停止工作的动画可视化。我已跟踪该问题,从matplotlib3.2.2升级到3.3.2。我比较了matplotlib3.2.2和3.3.2的文档,主要的变化是示例中的HMTLAnimationWriter和勘误表。我看不出我的代码有什么理由停止工作 我提出了一个建议 A) 预期行为 立柱末端的代码沿y方向上下移动一行。它通过matplotlib3.2.2成功地做到了这一点,但没有通过3.3.2。这在不同的设置下是可复制的 B) 问题 当我使用matplot
matplotlib
3.2.2升级到3.3.2。我比较了matplotlib
3.2.2和3.3.2的文档,主要的变化是示例中的HMTLAnimationWriter和勘误表。我看不出我的代码有什么理由停止工作
我提出了一个建议
A) 预期行为
立柱末端的代码沿y方向上下移动一行。它通过matplotlib
3.2.2成功地做到了这一点,但没有通过3.3.2。这在不同的设置下是可复制的
B) 问题
当我使用matplotlib
3.3.2时,将打开一个空图形
当我使用matplotlib
3.2.2从命令行(例如python test.py
)运行代码时,不会收到折旧警告或任何其他错误消息。类似于matplotlib
3.3.2。这一点已经通过了测试
- C1:配备Asrock Z370 P4、Nvidia 1050 Ti、i5-8600K的桌面。
通过以下方式进行测试:
- Python:3.8.3,matplotlib:3.2.2正常
- Python:3.8.3,matplotlib:3.3.2(有问题)
- C2:Acer Spin 5 SP513-52N笔记本电脑。
通过以下方式进行测试:
- Python:3.8.3,matplotlib:3.2.2正常
- Python:3.8.3,matplotlib:3.3.2(有问题)
- 根据用户评论:
通过以下方式进行测试:
- Win 10,Python:3.8.3,matplotlib:3.3.2(有问题)
- Ubuntu 20.04,Python:3.8.3,matplotlib:3.1.2正常
- Ubuntu 20.04,Python:3.8.3,更新为matplotlib:3.3.2(有问题)
在我的两个例子中,当我升级时问题出现了,当我降级时问题消失了。因此,我猜问题在于matplotlib
3.3.2
有趣的一点是,如果我使用Pillowriter创建动画gif,则生成的gif在所有版本的matplotlib
中都能按预期执行
问题
这是一个bug还是API的一个特性
如果这是一项功能,那么新的动画推荐方法是什么(最好是向后兼容)。似乎并非所有的FuncAnimation()
命令都会受到影响李>
如果它是一个bug,有解决方法吗
代码
我包含了一个MCVE代码,该代码再现了主要问题,可用于matplotlib
3.2.2,但不能用于3.3.2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
def create_animated_plot(xs, niter, xlim =(-1.5, 1.5), ylim = [-3, 3]):
line_coords = np.vstack(( np.array([-1,1]), np.array([0,0]) ))
boxData = [np.array([np.zeros(niter), xs])]
fig, ax1 = plt.subplots(1,1)
line, = ax1.plot([], [], lw=2)
ax1.set_ylabel('position')
ax1.set_ylim(ylim)
ax1.set_xlim(xlim)
lines = [ax1.plot([],[],lw=2,color="black")[0]]
def init():
lines[0].set_data([],[])
return lines
def animate(i):
xs = [boxData[0][0, i]]
ys = [boxData[0][1, i]]
lines[0].set_data(line_coords[0,:]+xs[0], line_coords[1,:]+ys[0])
return lines
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=niter, interval=10, blit=True)
niter = 1001
t = np.linspace(0,10,niter)
create_animated_plot(xs =np.sin(t), niter=niter)
plt.show()
附加信息
以下是我的原始代码中的图像(我在本文中将其简化为MCVE代码):
- 原始代码工作示例的动画gif:此图中有两个动画(顶部子图:框向上和向下移动,底部:穿过绘图的红线移动)
- matplotlib 3.3.2输出的png:两个动画都不会显示预期的行为。顶部甚至不会绘制框。在底部子图中,将为第一帧绘制红线,但它不会移动
请注意,此处发布的MCVE代码只创建了两个图形的上框,并显示了一条带有matplotlib
≤3.2.2,但使用matplotlib
3.3.2.的空帧问题在于gc现在更积极地收集对动画对象的引用。这与
一个简单的解决方法是传递参考,如下所示:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
def create_animated_plot(xs, niter, xlim =(-1.5, 1.5), ylim = [-3, 3]):
line_coords = np.vstack(( np.array([-1,1]), np.array([0,0]) ))
boxData = [np.array([np.zeros(niter), xs])]
fig, ax1 = plt.subplots(1,1)
line, = ax1.plot([], [], lw=2)
ax1.set_ylabel('position')
ax1.set_ylim(ylim)
ax1.set_xlim(xlim)
lines = [ax1.plot([],[],lw=2,color="black")[0]]
def init():
lines[0].set_data([],[])
return lines
def animate(i):
xs = [boxData[0][0, i]]
ys = [boxData[0][1, i]]
lines[0].set_data(line_coords[0,:]+xs[0], line_coords[1,:]+ys[0])
return lines
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=niter, interval=10, blit=True)
return anim # return anim object reference ########################################################
niter = 1001
t = np.linspace(0,10,niter)
anim = create_animated_plot(xs =np.sin(t), niter=niter) # assign to variable ###########################
plt.show()
如果有类,还可以将动画对象指定给self
注意:如果没有的帮助和耐心,我不可能想出这个答案。评论不可进行长时间的讨论;这段对话已经结束。