Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7.9k
Description
Summary
TimedAnimation
resets the event timer at the end of its_step()
method:
matplotlib/lib/matplotlib/animation.py
Line 1446 inf7b3def
self.event_source.interval=self._interval |
As far as I can tell, this is by design. The original commit included this comment:
matplotlib/lib/matplotlib/animation.py
Lines 314 to 318 in70e401f
def_loop_delay(self,*args): | |
# Reset the interval and change callbacks after the delay. | |
self.event_source.remove_callback(self._loop_delay) | |
self.event_source.interval=self._interval | |
self.event_source.add_callback(self._step) |
To me, this was suprising and it took me a while to get to the bottom of it. From the documentation I took that the event loop calls the animation target at exactly theinterval
specified. However, the current implementation means that it actually calls it atinterval + time_in_callback
. In case the callback does some heavy lifting, like processing data or communicating with an instrument, this can add significant overhead to the real interval between frames.
A MWE highlighting the effects of resetting the interval:
importmatplotlib.pyplotaspltimportnumpyasnpfrommatplotlibimportanimationdefupdate(frame):iflen(frame)<2:return []diff=np.diff(frame)avg.set_text(avg_txt.format(diff.mean()*1e3))cur.set_text(cur_txt.format(diff[-1]*1e3))return [avg,cur]defframe():times=deque(maxlen=100)whileTrue:time.sleep(0.1)times.append(time.perf_counter())yieldtimesfig,ax=plt.subplots(figsize=(1,1))ax.axis('off')avg_txt='avg: {:.3g} ms'cur_txt='cur: {:.3g} ms'avg=ax.text(0.5,0.75,avg_txt.format(0),va='center',ha='center')cur=ax.text(0.5,0.25,cur_txt.format(0),va='center',ha='center')anim=animation.FuncAnimation(fig,update,frame,repeat=False,cache_frame_data=False,interval=200)
With the current behavior, this results in an effective interval of 300 ms. Commenting outthe line resetting the interval results in the effective interval I would expect frominterval=200
, 200 ms.
Proposed fix
There might be reasonable usecases for resetting the interval, but I cannot see any right now. Hence, I would propose to leave the timer running uninterrupted, i.e., dropping
matplotlib/lib/matplotlib/animation.py
Line 1446 inf7b3def
self.event_source.interval=self._interval |