在事件处理程序中使用Matplotlib动画

时间:2016-12-27 20:08:00

标签: python animation matplotlib

我想在每次用户按下特定键时触发动画。我有数据代表一个动画情节(每帧不同的情节)和一个空图,所以想法是当你按R(例如)动画情节运行,如果你按{{1它再次运行。以下代码有效:

R

其中### Lots of code before fig = plt.figure() anim = animation.FuncAnimation(fig, animate, repeat=True) plt.show() 是我写的函数。当我运行它时,会弹出Matplotlib窗口并且动画一遍又一遍地运行。这很好,但是我喜欢用命令触发动画,所以我这样做了:

animate

事件记录由### 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添加到事件处理程序,现在当我按{ {1}}程序只是停止并且绘图窗口关闭。

如果global anim调用在某个函数中,R方法可以正常工作,如下所示:

global

但不在事件处理程序内。

我该怎么办?如何在事件处理程序中创建动画对象并使其保持活动状态?

更新:显然导致崩溃的原因是在FuncAnimation电话中def f(): global anim anim = animation.FuncAnimation(fig, animate) f() {我没有在我的例子中包含,因为我认为这是无关紧要的)。设置blit=True会停止崩溃,但是当我触发事件时仍然没有任何反应。

2 个答案:

答案 0 :(得分:1)

你必须保持对动画对象的实时引用,或者它(以及它的定时器)被垃圾收集。见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) 

答案 1 :(得分:0)

这不是一个完整的答案,但希望它可能对任何有同样问题的人有所帮助:受到@ tacaswell上述评论的启发我尝试将后端切换到TkAgg,现在它可以工作了。也许这是QT的错误?