@@ -319,3 +319,56 @@ def test_lazy_linux_headless():
319
319
if proc .returncode :
320
320
pytest .fail ("The subprocess returned with non-zero exit status "
321
321
f"{ proc .returncode } ." )
322
+
323
+
324
+ def _test_number_of_draws_script ():
325
+ from matplotlib import animation
326
+ import matplotlib .pyplot as plt
327
+
328
+ # If blitting is respected, this should result in
329
+ # only one "draw_event" being emitted
330
+ fig , ax = plt .subplots ()
331
+
332
+ def animate (i ):
333
+ # Create a new marker every time, instead of updating data
334
+ # this "misuse" of animate can trip up blitting, but it should
335
+ # not emit a new draw_event
336
+ return ax .plot (0 , 0 )
337
+
338
+ # Show the empty figure initially because some backends emit a
339
+ # draw event on canvas initialization, which we aren't interested
340
+ # in counting
341
+ plt .show (block = False )
342
+
343
+ # Connect to draw_event to count the number of events received
344
+ fig .canvas .mpl_connect ('draw_event' , print )
345
+
346
+ ani = animation .FuncAnimation (
347
+ fig , animate , frames = 10 , blit = True , repeat = False )
348
+
349
+ plt .show (block = False )
350
+ # Give the animation some time to draw before closing
351
+ # calling plt.close() from within the animation causes the
352
+ # animation timers to be called on a Nonetype object, potentially
353
+ # causing segfaults or anomalous failures
354
+ plt .pause (0.5 )
355
+
356
+
357
+ @pytest .mark .parametrize ("env" , _get_testable_interactive_backends ())
358
+ def test_number_of_draws (env ):
359
+ if env ["MPLBACKEND" ].startswith ("gtk" ):
360
+ # FIXME
361
+ pytest .skip ("GTK animation calls draw too many times" )
362
+
363
+ proc = subprocess .run (
364
+ [sys .executable , "-c" ,
365
+ inspect .getsource (_test_number_of_draws_script )
366
+ + "\n _test_number_of_draws_script()" ],
367
+ env = {** os .environ , "SOURCE_DATE_EPOCH" : "0" , ** env },
368
+ timeout = _test_timeout ,
369
+ stdout = subprocess .PIPE , universal_newlines = True )
370
+ if proc .returncode :
371
+ pytest .fail ("The subprocess returned with non-zero exit status "
372
+ f"{ proc .returncode } ." )
373
+ # Make sure we only got one draw event from the animation
374
+ assert proc .stdout .count ("DrawEvent" ) == 1
0 commit comments