diff --git a/doc/missing-references.json b/doc/missing-references.json index f2f4b7576da5..1bb005c9a18a 100644 --- a/doc/missing-references.json +++ b/doc/missing-references.json @@ -504,7 +504,7 @@ "lib/matplotlib/figure.py:docstring of matplotlib.figure.Figure.legend:220", "lib/matplotlib/figure.py:docstring of matplotlib.figure.FigureBase.legend:220", "lib/matplotlib/figure.py:docstring of matplotlib.figure.SubFigure.legend:220", - "lib/matplotlib/legend.py:docstring of matplotlib.legend.Legend:178", + "lib/matplotlib/legend.py:docstring of matplotlib.legend.Legend:179", "lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.figlegend:220", "lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.legend:219" ] @@ -522,11 +522,11 @@ }, "py:meth": { "AbstractPathEffect._update_gc": [ - "lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.SimpleLineShadow:43", - "lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.SimplePatchShadow:42", - "lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.TickedStroke:59", - "lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.withSimplePatchShadow:51", - "lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.withTickedStroke:54" + "lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.SimpleLineShadow:44", + "lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.SimplePatchShadow:43", + "lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.TickedStroke:60", + "lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.withSimplePatchShadow:52", + "lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.withTickedStroke:55" ], "FigureCanvasQTAgg.blit": [ "doc/api/prev_api_changes/api_changes_2.2.0.rst:199" @@ -802,7 +802,7 @@ "lib/matplotlib/figure.py:docstring of matplotlib.figure.Figure.legend:129", "lib/matplotlib/figure.py:docstring of matplotlib.figure.FigureBase.legend:129", "lib/matplotlib/figure.py:docstring of matplotlib.figure.SubFigure.legend:129", - "lib/matplotlib/legend.py:docstring of matplotlib.legend.Legend:87", + "lib/matplotlib/legend.py:docstring of matplotlib.legend.Legend:88", "lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.figlegend:129", "lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.legend:128" ], @@ -851,7 +851,7 @@ "lib/matplotlib/figure.py:docstring of matplotlib.figure.Figure.legend:129", "lib/matplotlib/figure.py:docstring of matplotlib.figure.FigureBase.legend:129", "lib/matplotlib/figure.py:docstring of matplotlib.figure.SubFigure.legend:129", - "lib/matplotlib/legend.py:docstring of matplotlib.legend.Legend:87", + "lib/matplotlib/legend.py:docstring of matplotlib.legend.Legend:88", "lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.figlegend:129", "lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.legend:128" ], @@ -977,7 +977,7 @@ "doc/api/_as_gen/matplotlib.animation.AVConvFileWriter.rst:39::1" ], "matplotlib.animation.AVConvWriter.args_key": [ - "doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:36::1" + "doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:37::1" ], "matplotlib.animation.AVConvWriter.bin_path": [ "doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:28::1" @@ -986,13 +986,13 @@ "doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:28::1" ], "matplotlib.animation.AVConvWriter.exec_key": [ - "doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:36::1" + "doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:37::1" ], "matplotlib.animation.AVConvWriter.finish": [ "doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:28::1" ], "matplotlib.animation.AVConvWriter.frame_size": [ - "doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:36::1" + "doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:37::1" ], "matplotlib.animation.AVConvWriter.grab_frame": [ "doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:28::1" @@ -1001,7 +1001,7 @@ "doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:28::1" ], "matplotlib.animation.AVConvWriter.output_args": [ - "doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:36::1" + "doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:37::1" ], "matplotlib.animation.AVConvWriter.saving": [ "doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:28::1" @@ -1009,6 +1009,9 @@ "matplotlib.animation.AVConvWriter.setup": [ "doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:28::1" ], + "matplotlib.animation.AVConvWriter.supported_formats": [ + "doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:37::1" + ], "matplotlib.animation.ArtistAnimation.new_frame_seq": [ "doc/api/_as_gen/matplotlib.animation.ArtistAnimation.rst:23::1" ], @@ -1070,7 +1073,7 @@ "doc/api/_as_gen/matplotlib.animation.FFMpegFileWriter.rst:28::1" ], "matplotlib.animation.FFMpegWriter.args_key": [ - "doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:36::1" + "doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:37::1" ], "matplotlib.animation.FFMpegWriter.bin_path": [ "doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:28::1" @@ -1079,13 +1082,13 @@ "doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:28::1" ], "matplotlib.animation.FFMpegWriter.exec_key": [ - "doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:36::1" + "doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:37::1" ], "matplotlib.animation.FFMpegWriter.finish": [ "doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:28::1" ], "matplotlib.animation.FFMpegWriter.frame_size": [ - "doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:36::1" + "doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:37::1" ], "matplotlib.animation.FFMpegWriter.grab_frame": [ "doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:28::1" @@ -1094,7 +1097,7 @@ "doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:28::1" ], "matplotlib.animation.FFMpegWriter.output_args": [ - "doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:36::1" + "doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:37::1" ], "matplotlib.animation.FFMpegWriter.saving": [ "doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:28::1" @@ -1102,6 +1105,9 @@ "matplotlib.animation.FFMpegWriter.setup": [ "doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:28::1" ], + "matplotlib.animation.FFMpegWriter.supported_formats": [ + "doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:37::1" + ], "matplotlib.animation.FileMovieWriter.args_key": [ "lib/matplotlib/animation.py:docstring of matplotlib.animation.FileMovieWriter.clear_temp:1::1" ], @@ -1123,6 +1129,9 @@ "matplotlib.animation.FileMovieWriter.saving": [ "doc/api/_as_gen/matplotlib.animation.FileMovieWriter.rst:28::1" ], + "matplotlib.animation.FileMovieWriter.supported_formats": [ + "lib/matplotlib/animation.py:docstring of matplotlib.animation.FileMovieWriter.clear_temp:1::1" + ], "matplotlib.animation.FuncAnimation.pause": [ "lib/matplotlib/animation.py:docstring of matplotlib.animation.FuncAnimation.new_frame_seq:1::1" ], @@ -1202,7 +1211,7 @@ "doc/api/_as_gen/matplotlib.animation.ImageMagickFileWriter.rst:28::1" ], "matplotlib.animation.ImageMagickWriter.args_key": [ - "doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:37::1" + "doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:38::1" ], "matplotlib.animation.ImageMagickWriter.bin_path": [ "doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:28::1" @@ -1211,16 +1220,16 @@ "doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:28::1" ], "matplotlib.animation.ImageMagickWriter.delay": [ - "doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:37::1" + "doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:38::1" ], "matplotlib.animation.ImageMagickWriter.exec_key": [ - "doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:37::1" + "doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:38::1" ], "matplotlib.animation.ImageMagickWriter.finish": [ "doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:28::1" ], "matplotlib.animation.ImageMagickWriter.frame_size": [ - "doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:37::1" + "doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:38::1" ], "matplotlib.animation.ImageMagickWriter.grab_frame": [ "doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:28::1" @@ -1229,7 +1238,7 @@ "doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:28::1" ], "matplotlib.animation.ImageMagickWriter.output_args": [ - "doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:37::1" + "doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:38::1" ], "matplotlib.animation.ImageMagickWriter.saving": [ "doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:28::1" @@ -1237,6 +1246,9 @@ "matplotlib.animation.ImageMagickWriter.setup": [ "doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:28::1" ], + "matplotlib.animation.ImageMagickWriter.supported_formats": [ + "doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:38::1" + ], "matplotlib.animation.MovieWriter.frame_size": [ "lib/matplotlib/animation.py:docstring of matplotlib.animation.MovieWriter.args_key:1::1" ], diff --git a/lib/matplotlib/animation.py b/lib/matplotlib/animation.py index 4d76953dd512..48a3ae41ed09 100644 --- a/lib/matplotlib/animation.py +++ b/lib/matplotlib/animation.py @@ -31,6 +31,7 @@ import warnings import numpy as np +from PIL import Image import matplotlib as mpl from matplotlib._animation_data import ( @@ -263,6 +264,10 @@ class MovieWriter(AbstractMovieWriter): exec_key = cbook._deprecate_privatize_attribute("3.3") args_key = cbook._deprecate_privatize_attribute("3.3") + # Pipe-based writers only support RGBA, but file-based ones support more + # formats. + supported_formats = ["rgba"] + def __init__(self, fps=5, codec=None, bitrate=None, extra_args=None, metadata=None): """ @@ -296,8 +301,7 @@ def __init__(self, fps=5, codec=None, bitrate=None, extra_args=None, super().__init__(fps=fps, metadata=metadata, codec=codec, bitrate=bitrate) - - self.frame_format = 'rgba' + self.frame_format = self.supported_formats[0] self.extra_args = extra_args def _adjust_frame_size(self): @@ -471,6 +475,10 @@ def frame_format(self, frame_format): if frame_format in self.supported_formats: self._frame_format = frame_format else: + cbook._warn_external( + f"Ignoring file format {frame_format!r} which is not " + f"supported by {type(self).__name__}; using " + f"{self.supported_formats[0]} instead.") self._frame_format = self.supported_formats[0] def _base_temp_name(self): @@ -521,7 +529,6 @@ def setup(self, fig, outfile, dpi=None): self._frames = [] def grab_frame(self, **savefig_kwargs): - from PIL import Image buf = BytesIO() self.fig.savefig( buf, **{**savefig_kwargs, "format": "rgba", "dpi": self.dpi}) @@ -736,15 +743,18 @@ class ImageMagickFileWriter(ImageMagickBase, FileMovieWriter): Frames are written to temporary files on disk and then stitched together at the end. - """ supported_formats = ['png', 'jpeg', 'ppm', 'tiff', 'sgi', 'bmp', 'pbm', 'raw', 'rgba'] def _args(self): - return ([self.bin_path(), '-delay', str(self.delay), '-loop', '0', - '%s*.%s' % (self.temp_prefix, self.frame_format)] + # Force format: ImageMagick does not recognize 'raw'. + fmt = 'rgba:' if self.frame_format == 'raw' else '' + return ([self.bin_path(), + '-size', '%ix%i' % self.frame_size, '-depth', '8', + '-delay', str(self.delay), '-loop', '0', + '%s%s*.%s' % (fmt, self.temp_prefix, self.frame_format)] + self.output_args)