diff --git a/lib/matplotlib/tests/test_animation.py b/lib/matplotlib/tests/test_animation.py index 8049f4998a3a..2e6fef9ff3f4 100644 --- a/lib/matplotlib/tests/test_animation.py +++ b/lib/matplotlib/tests/test_animation.py @@ -13,6 +13,33 @@ from matplotlib import animation +@pytest.fixture() +def anim(request): + """Create a simple animation (with options).""" + fig, ax = plt.subplots() + line, = ax.plot([], []) + + ax.set_xlim(0, 10) + ax.set_ylim(-1, 1) + + def init(): + line.set_data([], []) + return line, + + def animate(i): + x = np.linspace(0, 10, 100) + y = np.sin(x + i) + line.set_data(x, y) + return line, + + # "klass" can be passed to determine the class returned by the fixture + kwargs = dict(getattr(request, 'param', {})) # make a copy + klass = kwargs.pop('klass', animation.FuncAnimation) + if 'frames' not in kwargs: + kwargs['frames'] = 5 + return klass(fig=fig, func=animate, init_func=init, **kwargs) + + class NullMovieWriter(animation.AbstractMovieWriter): """ A minimal MovieWriter. It doesn't actually write anything. @@ -40,26 +67,8 @@ def finish(self): pass -def make_animation(**kwargs): - fig, ax = plt.subplots() - line, = ax.plot([]) - - def init(): - pass - - def animate(i): - line.set_data([0, 1], [0, i]) - return line, - - return animation.FuncAnimation(fig, animate, **kwargs) - - -def test_null_movie_writer(): +def test_null_movie_writer(anim): # Test running an animation with NullMovieWriter. - - num_frames = 5 - anim = make_animation(frames=num_frames) - filename = "unused.null" dpi = 50 savefig_kwargs = dict(foo=0) @@ -68,17 +77,17 @@ def test_null_movie_writer(): anim.save(filename, dpi=dpi, writer=writer, savefig_kwargs=savefig_kwargs) - assert writer.fig == plt.figure(1) # The figure used by make_animation. + assert writer.fig == plt.figure(1) # The figure used by anim fixture assert writer.outfile == filename assert writer.dpi == dpi assert writer.args == () assert writer.savefig_kwargs == savefig_kwargs - assert writer._count == num_frames - + assert writer._count == anim.save_count -def test_animation_delete(): - anim = make_animation(frames=5) +@pytest.mark.parametrize('anim', [dict(klass=dict)], indirect=['anim']) +def test_animation_delete(anim): + anim = animation.FuncAnimation(**anim) with pytest.warns(Warning, match='Animation was deleted'): del anim gc.collect() @@ -140,44 +149,62 @@ def isAvailable(cls): # design more sophisticated tests which compare resulting frames a-la # matplotlib.testing.image_comparison @pytest.mark.parametrize('writer, output', WRITER_OUTPUT) -def test_save_animation_smoketest(tmpdir, writer, output): +@pytest.mark.parametrize('anim', [dict(klass=dict)], indirect=['anim']) +def test_save_animation_smoketest(tmpdir, writer, output, anim): if not animation.writers.is_available(writer): pytest.skip("writer '%s' not available on this system" % writer) - fig, ax = plt.subplots() - line, = ax.plot([], []) - - ax.set_xlim(0, 10) - ax.set_ylim(-1, 1) + anim = animation.FuncAnimation(**anim) dpi = None codec = None if writer == 'ffmpeg': # Issue #8253 - fig.set_size_inches((10.85, 9.21)) + anim._fig.set_size_inches((10.85, 9.21)) dpi = 100. codec = 'h264' - def init(): - line.set_data([], []) - return line, - - def animate(i): - x = np.linspace(0, 10, 100) - y = np.sin(x + i) - line.set_data(x, y) - return line, - # Use temporary directory for the file-based writers, which produce a file # per frame with known names. with tmpdir.as_cwd(): - anim = animation.FuncAnimation(fig, animate, init_func=init, frames=5) anim.save(output, fps=30, writer=writer, bitrate=500, dpi=dpi, codec=codec) + with pytest.warns(None): + del anim -def test_no_length_frames(): - (make_animation(frames=iter(range(5))) - .save('unused.null', writer=NullMovieWriter())) +@pytest.mark.parametrize('writer', [ + pytest.param( + 'ffmpeg', marks=pytest.mark.skipif( + not animation.FFMpegWriter.isAvailable(), + reason='Requires FFMpeg')), + pytest.param( + 'imagemagick', marks=pytest.mark.skipif( + not animation.ImageMagickWriter.isAvailable(), + reason='Requires ImageMagick')), +]) +@pytest.mark.parametrize('html, want', [ + ('none', None), + ('html5', '