Matplotlib第一帧后停止动画 [英] Matplotlib stops animating after first frame
问题描述
我试图动画2次要情节,每多行。我使用的 Matplotlib ,而我使用<$c$c>FuncAnimation$c$c>,它是由许多的动画范例的。
使用动画:
如果我尝试动画吧,我只得到第一帧的结果:
如果不使用动画:
如果我手动调用我的 update_lines
函数,它工作正常。
code:
以下是完整code(取消注释3所示的行的main()
的作品,但我想看到它在实时更新,因此,尝试使用动画)。
进口matplotlib.pyplot如PLT
从matplotlib.animation进口FuncAnimation
高清make_subplots():
高清setup_axes(轴):
在轴AX:
ax.set_xbound(0,100)根据需要#结合将改变。
ax.set_ylim(0,1)#限制不会自动改变。 高清make_lines(轴):
标签=('A','B','C')
行= []
在轴AX:
ax_lines = []
在标签标签:
的x,y = [0],[0]
行= ax.plot(X,Y,标签=标签)#逗号拆箱。
ax_lines.append((线,X,Y))
lines.append(ax_lines)
返回线 无花果,轴= plt.subplots(2,1,sharex = TRUE,sharey = TRUE)
线= make_lines(轴)
setup_axes(轴)
返回无花果,轴,线
高清make_data():
在的xrange(100)I:
打印make_data()',我
数据字典=()
在('一个','B','C')标签:
从随机随机进口
数据[标签] =随机()
产量第(i + 1,数据)
高清update_lines(数据线):
打印update_lines()',数据线
updated_lines = []
在线路ax_lines:
为线,X,Y在ax_lines:
标签= line.get_label()
x.append(数据[0])
y.append(数据[1] [标签])
line.set_data(X,Y)
updated_lines.append(线)
高清的main():
无花果,斧头,线条= make_subplots() #取消这3条线,和它的作品!
#NEW_DATA = make_data()
#在NEW_DATA数据:
#update_lines(数据行) FuncAnimation(图=图,
FUNC = update_lines,
帧= make_data,
fargs =(线,),
间隔= 10,
的blit = FALSE) plt.show()
如果__name__ =='__main__':
主要()
(无证?)挂钩
所以,我周围挖 matplotlib.animation.Animation
的源 - code,我注意到在 __ init__这些线路()
功能:
#清除初始帧
self._init_draw()#相反,从现在开始的事件源,我们连接到人物的
#draw_event,让我们曾经的身影已经绘就只启动。
self._first_draw_id = fig.canvas.mpl_connect('draw_event',self._start)
听起来很耳熟...
这看起来正确为止。在 self._init_draw()
呼叫立即吸引我的第一帧。然后动画对象挂钩插入数字对象,并等待该图以试图绘制任何更多的帧的动画之前被显示。
尤里卡!
关键词是:animation-的目标即可。因为我不是在以后的使用动画实例规划(例如,画一个电影),我没有把它分配给一个变量。的实际上的,我被大叫按 pyflakes 因为局部变量'...'被分配到,但从未使用过
。
但是,因为所有的功能依赖上了钩,当画布终于显示我presume Python的垃圾收集去掉了动画实例---因为它从来没有分配给一个变量---因此,动画永远不能启动。
的修复
简单实例 FuncAnimation
实例分配给一个变量,一切工作正常!
动画= FuncAnimation(图=图,
FUNC = update_lines,
帧= make_data,
fargs =(线,),
间隔= 10,
的blit = FALSE)
I'm trying to animate two subplots, each with multiple lines. I am using Matplotlib, and I am using the FuncAnimation
, which is used by many of the animation examples.
Using animation:
If I try to animate it, I only get the result of the first frame:
Without using animation:
If I manually call my update_lines
function, it works fine.
Code:
Below is the full code (uncommenting the 3 indicated lines in main()
works, but I would like to see it update in real-time, hence trying to use the animation).
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
def make_subplots():
def setup_axes(axes):
for ax in axes:
ax.set_xbound(0, 100) # bound will change as needed.
ax.set_ylim(0, 1) # limit won't change automatically.
def make_lines(axes):
labels = ('a', 'b', 'c')
lines = []
for ax in axes:
ax_lines = []
for label in labels:
x, y = [0], [0]
line, = ax.plot(x, y, label=label) # comma for unpacking.
ax_lines.append((line, x, y))
lines.append(ax_lines)
return lines
fig, axes = plt.subplots(2, 1, sharex=True, sharey=True)
lines = make_lines(axes)
setup_axes(axes)
return fig, axes, lines
def make_data():
for i in xrange(100):
print 'make_data():', i
data = dict()
for label in ('a', 'b', 'c'):
from random import random
data[label] = random()
yield (i + 1, data)
def update_lines(data, lines):
print 'update_lines():', data, lines
updated_lines = []
for ax_lines in lines:
for line, x, y in ax_lines:
label = line.get_label()
x.append(data[0])
y.append(data[1][label])
line.set_data(x, y)
updated_lines.append(line)
def main():
fig, axes, lines = make_subplots()
# Uncomment these 3 lines, and it works!
# new_data = make_data()
# for data in new_data:
# update_lines(data, lines)
FuncAnimation(fig=fig,
func=update_lines,
frames=make_data,
fargs=(lines,),
interval=10,
blit=False)
plt.show()
if __name__ == '__main__':
main()
(Undocumented?) Hooks
So, I was digging around the source-code of matplotlib.animation.Animation
, and I noticed these lines in the __init__()
function:
# Clear the initial frame
self._init_draw()
# Instead of starting the event source now, we connect to the figure's
# draw_event, so that we only start once the figure has been drawn.
self._first_draw_id = fig.canvas.mpl_connect('draw_event', self._start)
Sounds familiar...
This looks right so far. The self._init_draw()
call draws my first frame immediately. Then the animation-object hooks into the figure-object and waits for the figure to be shown before attempting to draw any more frames for the animation.
Eureka!
The keyword is: animation-object. Since I wasn't planning on using the animation instance later (for example, to draw a movie), I didn't assign it to a variable. In fact, I was being yelled at by pyflakes because Local variable '...' is assigned to but never used
.
But because all of the functionality relies on the hook, when the canvas is finally shown I presume Python's garbage collection has removed the Animation instance---since it was never assigned to a variable---and therefore the animation can never be started.
The fix
Simply assign the instance FuncAnimation
instance to a variable, and everything works as expected!
anim = FuncAnimation(fig=fig,
func=update_lines,
frames=make_data,
fargs=(lines,),
interval=10,
blit=False)
这篇关于Matplotlib第一帧后停止动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!