@@ -319,3 +319,56 @@ def test_lazy_linux_headless():
319319 if proc .returncode :
320320 pytest .fail ("The subprocess returned with non-zero exit status "
321321 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