44from pathlib import Path
55from typing import Literal
66from unittest import mock
7+ from contextlib import contextmanager
78
89import matplotlib
910import numpy as np
@@ -219,12 +220,26 @@ def playback_events(
219220 if prog_bar and _prog_bar :
220221 pbar = tqdm (total = N_frames )
221222
223+ def fake_draw (* args , ** kwargs ):
224+ pass
225+
226+ @contextmanager
227+ def patch_draw (fig ):
228+ orig_draw = fig .canvas .draw
229+ try :
230+ fig .canvas .draw = fake_draw
231+ yield
232+ finally :
233+ fig .canvas .draw = orig_draw
234+
222235 def animate (i ):
223236 idx = event_frames == i
224237 if np .sum (idx ) != 0 :
225238 for event in mock_events [idx ]:
226239 # event = mock_events[i]
227- accessors [event ._figname ].canvas .callbacks .process (event .name , event )
240+ fig = accessors [event ._figname ]
241+ with patch_draw (fig ):
242+ fig .canvas .callbacks .process (event .name , event )
228243 if event .name == "motion_notify_event" :
229244 # now set the cursor invisible so multiple don't show up
230245 # if there are multiple figures
@@ -237,16 +252,10 @@ def animate(i):
237252 # transform is crucial or else the cursor will show up in a weirdly
238253 # scaled position. This is true even with setting `transform=None`
239254 # on the origin `plot` call
240- f = _figs [event ._figname ]
241255 xy = transforms [event ._figname ].transform ([event .x , event .y ])
242256 fake_cursors [event ._figname ].set_data ([xy [0 ]], [xy [1 ]])
243257 fake_cursors [event ._figname ].set_visible (True )
244258
245- # theres got to be a clever way to avoid doing these gazillion draws
246- # maybe monkeypatching the figure's draw event?
247- for f in _figs .values ():
248- f .canvas .draw ()
249-
250259 if prog_bar and _prog_bar :
251260 pbar .update (1 )
252261 if outputs is not None :
0 commit comments