@@ -319,3 +319,57 @@ 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
+ plt .pause (0.1 )
343
+
344
+ # Connect to draw_event to count the number of events received
345
+ fig .canvas .mpl_connect ('draw_event' , print )
346
+
347
+ ani = animation .FuncAnimation (
348
+ fig , animate , frames = 10 , blit = True , repeat = False )
349
+
350
+ plt .show (block = False )
351
+ # Give the animation some time to draw before closing
352
+ # calling plt.close() from within the animation causes the
353
+ # animation timers to be called on a Nonetype object, potentially
354
+ # causing segfaults or anomalous failures
355
+ plt .pause (0.5 )
356
+
357
+
358
+ @pytest .mark .parametrize ("env" , _get_testable_interactive_backends ())
359
+ def test_number_of_draws (env ):
360
+ if env ["MPLBACKEND" ].startswith ("gtk" ):
361
+ # FIXME
362
+ pytest .skip ("GTK animation calls draw too many times" )
363
+
364
+ proc = subprocess .run (
365
+ [sys .executable , "-c" ,
366
+ inspect .getsource (_test_number_of_draws_script )
367
+ + "\n _test_number_of_draws_script()" ],
368
+ env = {** os .environ , "SOURCE_DATE_EPOCH" : "0" , ** env },
369
+ timeout = _test_timeout ,
370
+ stdout = subprocess .PIPE , universal_newlines = True )
371
+ if proc .returncode :
372
+ pytest .fail ("The subprocess returned with non-zero exit status "
373
+ f"{ proc .returncode } ." )
374
+ # Make sure we only got one draw event from the animation
375
+ assert proc .stdout .count ("DrawEvent" ) == 1
0 commit comments