python matplotlib动画中的停止/启动/暂停
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16732379/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
stop / start / pause in python matplotlib animation
提问by Jaco Vermaak
I'm using FuncAnimation in matplotlib's animation module for some basic animation. This function perpetually loops through the animation. Is there a way by which I can pause and restart the animation by, say, mouse clicks?
我在 matplotlib 的动画模块中使用 FuncAnimation 来制作一些基本动画。此函数会永久循环播放动画。有没有办法让我可以通过鼠标点击来暂停和重新启动动画?
采纳答案by unutbu
Here is a FuncAnimation examplewhich I modified to pause on mouse clicks.
Since the animation is driven by a generator function, simData, when the global variable pauseis True, yielding the same data makes the animation appear paused.
这是一个 FuncAnimation 示例,我将其修改为在鼠标点击时暂停。由于动画是由生成器函数驱动的simData,当全局变量pause为 True 时,产生相同的数据会使动画出现暂停。
The value of pausedis toggled by setting up an event callback:
paused通过设置事件回调来切换的值:
def onClick(event):
global pause
pause ^= True
fig.canvas.mpl_connect('button_press_event', onClick)
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
pause = False
def simData():
t_max = 10.0
dt = 0.05
x = 0.0
t = 0.0
while t < t_max:
if not pause:
x = np.sin(np.pi*t)
t = t + dt
yield x, t
def onClick(event):
global pause
pause ^= True
def simPoints(simData):
x, t = simData[0], simData[1]
time_text.set_text(time_template%(t))
line.set_data(t, x)
return line, time_text
fig = plt.figure()
ax = fig.add_subplot(111)
line, = ax.plot([], [], 'bo', ms=10)
ax.set_ylim(-1, 1)
ax.set_xlim(0, 10)
time_template = 'Time = %.1f s'
time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes)
fig.canvas.mpl_connect('button_press_event', onClick)
ani = animation.FuncAnimation(fig, simPoints, simData, blit=False, interval=10,
repeat=True)
plt.show()
回答by fred
This works...
这工作...
anim = animation.FuncAnimation(fig, animfunc[,..other args])
#pause
anim.event_source.stop()
#unpause
anim.event_source.start()
回答by woodenflute
Combining both the answers from @fred and @unutbu here, we can add an onClick function after creating the animation:
在这里结合@fred 和@unutbu 的回答,我们可以在创建动画后添加一个 onClick 函数:
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig = plt.figure()
def run_animation():
anim_running = True
def onClick(event):
nonlocal anim_running
if anim_running:
anim.event_source.stop()
anim_running = False
else:
anim.event_source.start()
anim_running = True
def animFunc( ...args... ):
# Animation update function here
fig.canvas.mpl_connect('button_press_event', onClick)
anim = animation.FuncAnimation(fig, animFunc[,...other args])
run_animation()
Now we can simply stop or start the animation with clicks.
现在我们可以简单地通过点击停止或开始动画。
回答by Peter9192
I landed on this page trying to implement the same functionality, pausing matplotlibs animation. The other answers are great, but in addition I wanted to be able to manually loop through the frames using the arrow keys. For anyone looking for the same functionality, here's my implementation:
我登陆这个页面试图实现相同的功能,暂停 matplotlibs 动画。其他答案很好,但除此之外,我还希望能够使用箭头键手动循环浏览帧。对于任何寻找相同功能的人,这是我的实现:
import matplotlib.pyplot as plt
import matplotlib.animation as ani
fig, ax = plt.subplots()
txt = fig.text(0.5,0.5,'0')
def update_time():
t = 0
t_max = 10
while t<t_max:
t += anim.direction
yield t
def update_plot(t):
txt.set_text('%s'%t)
return txt
def on_press(event):
if event.key.isspace():
if anim.running:
anim.event_source.stop()
else:
anim.event_source.start()
anim.running ^= True
elif event.key == 'left':
anim.direction = -1
elif event.key == 'right':
anim.direction = +1
# Manually update the plot
if event.key in ['left','right']:
t = anim.frame_seq.next()
update_plot(t)
plt.draw()
fig.canvas.mpl_connect('key_press_event', on_press)
anim = ani.FuncAnimation(fig, update_plot, frames=update_time,
interval=1000, repeat=True)
anim.running = True
anim.direction = +1
plt.show()
Some notes:
一些注意事项:
- To be able to modify the values of
runninganddirection, I assigned them toanim. It avoids using nonlocal (not avaible in Python2.7) or global (not desirable since I'm running this code within another function). Not sure whether this is good practice, but I found it quite elegant. - For the manual update, I'm accessing
anim's generator object that FuncAnimation uses to update the plot. This ensures that when I resume the animation, it starts from the active frame rather than from where it was originally paused.
- 为了能够修改的值
running和direction,我分配他们anim。它避免使用非本地(Python2.7 中不可用)或全局(不可取,因为我在另一个函数中运行此代码)。不确定这是否是好的做法,但我发现它非常优雅。 - 对于手动更新,我正在访问
animFuncAnimation 用来更新绘图的生成器对象。这确保当我恢复动画时,它从活动帧开始,而不是从最初暂停的位置开始。

