我编写了一个简单的动画示例,并以每秒30帧的速度运行,但它的运行速度似乎比我预期的要快得多。我给它计时,果然,它是以双倍的速度运行的。似乎有两个计时器运行的实例稍微有点偏移。下面是一个复制这种行为的简短示例。但是,错误只发生在70%左右的时间。在使用动画包的过程中是否有什么地方我做错了,或者我是否应该深入研究matplotlib代码并尝试在GitHub上提交一个问题?你知道吗
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
import time
class TestAnimation(object):
def __init__(self, fps=30):
# Set up animation
self.render_dt = 1.0/fps
self.t = time.time()
self.fig = plt.figure(3)
self.line, = plt.plot([0, 1, 2], [0, 2, 1])
# Run animation
frames = np.arange(100)
print "interval = %f ms" % (self.render_dt * 1000)
self.started = False
self.ani = animation.FuncAnimation(self.fig, self.update, frames,
interval=self.render_dt * 1000, blit=True)
# raw_input("Push enter to begin animation")
self.started = True
def show(self):
plt.show()
def update(self, idx):
# if idx > 0 and not self.started:
# raise Exception("Animation has not yet been started!")
dt = time.time() - self.t
self.t = time.time()
print "dt = %.3f, idx = %d, t = %f" % (dt, idx, time.time())
self.line.set_data([0, 1, 2], [0, 2, float(idx)/50])
return [self.line]
anim = TestAnimation()
anim.show()
我终于弄明白发生了什么事。结果表明,只有在使用TkAgg后端时才会出现问题,并且问题是由回调期间重新启动TkTimer引起的。你知道吗
Tk使用单次回调,这意味着Matplotlib的TkTimer类必须在每次使用Tk.after()函数关闭计时器时创建一个新的Tk回调。当TkTimer停止时,它使用Tk.after_cancel()函数取消Tk回调。但是,直到TkTimer回调结束时才创建新的Tk回调,这意味着尝试在TkTimer回调中停止TkTimer将失败。然后,启动计时器会导致创建第二个Tk回调,从而导致动画以双倍的速度运行。下面是一个简短的代码片段,再现了这个问题:
下面的输出显示计时器以10 Hz的预期速度运行,直到在回调期间计时器重新启动。当计时器重新启动时,每10秒钟触发两次回调,而不是仅触发1次。你知道吗
通过查看animation类,可以看出为什么TkTimer会在回调中重新启动。在animation类中的第一个TkTimer回调中,它绘制了一些东西,这些东西将控制Tk。作为绘图的结果,Tk触发resize\u事件和draw\u事件。动画类在调整大小时暂停TkTimer,并在调整完成后重新启动。不管出于什么原因,有时这些回调发生在TkTimer回调内部,从而导致这些问题的发生。你知道吗
相关问题 更多 >
编程相关推荐