我有一个动画,每次用户按下特定键时,我都想发射动画。我有代表动画图(因此每帧不同的绘图)和一个空图的数据,因此想法是,当您按R
(例如)动画绘图运行时,如果您再次按R
,它将再次运行。以下代码有效:
### Lots of code before
fig = plt.figure()
anim = animation.FuncAnimation(fig, animate, repeat=True)
plt.show()
其中 animate
是我写的函数。当我运行此操作时,Matplotlib窗口会弹出,动画一遍又一遍地运行。这很好,但是我希望动画以命令开火,所以我这样做了:
### Lots of code before
def press(event):
if event.key == "r":
print("r") # for debugging purposes
anim = animation.FuncAnimation(fig, animate)
fig = plt.figure()
fig.canvas.mpl_connect("key_press_event", press)
plt.show()
事件登记为print
所证明的,但什么也没有发生,只是一个空的情节窗口。现在,我读到这是不起作用的,因为动画对象在功能结束后需要保持活力,因此我在创建动画对象之前将global anim
添加到了事件处理程序中,现在当我按R
时,该程序简单地停止,然后绘图窗口关闭。
如果FuncAnimation
调用在某些功能中,则global
方法可以正常工作,例如:
def f():
global anim
anim = animation.FuncAnimation(fig, animate)
f()
,但不在活动处理程序中。
我该怎么办?如何在事件处理程序中创建动画对象并使其保持活力?
更新:显然导致崩溃的原因是FuncAnimation
呼叫中的blit=True
(我在示例中没有包括在示例中,因为我认为这是无关紧要的)。设置blit=False
停止崩溃,但是当我触发事件时,仍然什么也不会发生。
您必须对动画对象进行实时参考,或者(和计时器)收集垃圾。请参阅http://matplotlib.org/devdocs/api/animation_api.html#animation
奇怪的是,global
技术在事件回调中不起作用,但是如果是这样,最好的方法可能是使小型助手类
class AnimManager:
def __init__(self):
self.anim = None
def __call__(self, event):
fig = make_a_figure_function()
self.anim = animation.FuncAnimation(fig, animate)
am = AnimManager()
fig.canvas.mpl_connect("key_press_event", am)
这不是一个完整的答案,但希望它对有相同问题的任何人有帮助:受 @tacaswell上面的评论的启发,我尝试将后端切换到tkagg,现在可以使用。也许是QT的错误?