Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6062833

Browse files
committed
Cleanup Animation frame_formats.
- Warn if the requested frame format is unsupported and fallback occurs. - ImageMagickFileWriter supports 'rgba' but requires explicit frame_size and depth to do so (they are the same as for ImageMagickWriter, and passing them doesn't negatively impact other formats); it does not support 'raw' (per https://imagemagick.org/script/formats.php) but we can just override it as 'rgba'. Test script: ```python import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation fig, ax = plt.subplots() x = np.arange(0, 2*np.pi, 0.01) line, = ax.plot(x, np.sin(x)) def animate(i): line.set_ydata(np.sin(x + i / 50)) # update the data. return line, ani = animation.FuncAnimation( fig, animate, interval=50, blit=True, save_count=20) plt.rcParams["animation.frame_format"] = "rgba" # or "raw" writer = animation.FFMpegFileWriter() # or animation.ImageMagickFileWriter() ani.save("/tmp/movie.mp4", writer=writer) ``` (Also move import of PIL up, as it's a standard dependency now.)
1 parent ff15ca9 commit 6062833

File tree

2 files changed

+49
-27
lines changed

2 files changed

+49
-27
lines changed

doc/missing-references.json

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@
504504
"lib/matplotlib/figure.py:docstring of matplotlib.figure.Figure.legend:220",
505505
"lib/matplotlib/figure.py:docstring of matplotlib.figure.FigureBase.legend:220",
506506
"lib/matplotlib/figure.py:docstring of matplotlib.figure.SubFigure.legend:220",
507-
"lib/matplotlib/legend.py:docstring of matplotlib.legend.Legend:178",
507+
"lib/matplotlib/legend.py:docstring of matplotlib.legend.Legend:179",
508508
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.figlegend:220",
509509
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.legend:219"
510510
]
@@ -522,11 +522,11 @@
522522
},
523523
"py:meth": {
524524
"AbstractPathEffect._update_gc": [
525-
"lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.SimpleLineShadow:43",
526-
"lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.SimplePatchShadow:42",
527-
"lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.TickedStroke:59",
528-
"lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.withSimplePatchShadow:51",
529-
"lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.withTickedStroke:54"
525+
"lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.SimpleLineShadow:44",
526+
"lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.SimplePatchShadow:43",
527+
"lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.TickedStroke:60",
528+
"lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.withSimplePatchShadow:52",
529+
"lib/matplotlib/patheffects.py:docstring of matplotlib.patheffects.withTickedStroke:55"
530530
],
531531
"FigureCanvasQTAgg.blit": [
532532
"doc/api/prev_api_changes/api_changes_2.2.0.rst:199"
@@ -802,7 +802,7 @@
802802
"lib/matplotlib/figure.py:docstring of matplotlib.figure.Figure.legend:129",
803803
"lib/matplotlib/figure.py:docstring of matplotlib.figure.FigureBase.legend:129",
804804
"lib/matplotlib/figure.py:docstring of matplotlib.figure.SubFigure.legend:129",
805-
"lib/matplotlib/legend.py:docstring of matplotlib.legend.Legend:87",
805+
"lib/matplotlib/legend.py:docstring of matplotlib.legend.Legend:88",
806806
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.figlegend:129",
807807
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.legend:128"
808808
],
@@ -851,7 +851,7 @@
851851
"lib/matplotlib/figure.py:docstring of matplotlib.figure.Figure.legend:129",
852852
"lib/matplotlib/figure.py:docstring of matplotlib.figure.FigureBase.legend:129",
853853
"lib/matplotlib/figure.py:docstring of matplotlib.figure.SubFigure.legend:129",
854-
"lib/matplotlib/legend.py:docstring of matplotlib.legend.Legend:87",
854+
"lib/matplotlib/legend.py:docstring of matplotlib.legend.Legend:88",
855855
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.figlegend:129",
856856
"lib/matplotlib/pyplot.py:docstring of matplotlib.pyplot.legend:128"
857857
],
@@ -977,7 +977,7 @@
977977
"doc/api/_as_gen/matplotlib.animation.AVConvFileWriter.rst:39:<autosummary>:1"
978978
],
979979
"matplotlib.animation.AVConvWriter.args_key": [
980-
"doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:36:<autosummary>:1"
980+
"doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:37:<autosummary>:1"
981981
],
982982
"matplotlib.animation.AVConvWriter.bin_path": [
983983
"doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:28:<autosummary>:1"
@@ -986,13 +986,13 @@
986986
"doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:28:<autosummary>:1"
987987
],
988988
"matplotlib.animation.AVConvWriter.exec_key": [
989-
"doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:36:<autosummary>:1"
989+
"doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:37:<autosummary>:1"
990990
],
991991
"matplotlib.animation.AVConvWriter.finish": [
992992
"doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:28:<autosummary>:1"
993993
],
994994
"matplotlib.animation.AVConvWriter.frame_size": [
995-
"doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:36:<autosummary>:1"
995+
"doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:37:<autosummary>:1"
996996
],
997997
"matplotlib.animation.AVConvWriter.grab_frame": [
998998
"doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:28:<autosummary>:1"
@@ -1001,14 +1001,17 @@
10011001
"doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:28:<autosummary>:1"
10021002
],
10031003
"matplotlib.animation.AVConvWriter.output_args": [
1004-
"doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:36:<autosummary>:1"
1004+
"doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:37:<autosummary>:1"
10051005
],
10061006
"matplotlib.animation.AVConvWriter.saving": [
10071007
"doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:28:<autosummary>:1"
10081008
],
10091009
"matplotlib.animation.AVConvWriter.setup": [
10101010
"doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:28:<autosummary>:1"
10111011
],
1012+
"matplotlib.animation.AVConvWriter.supported_formats": [
1013+
"doc/api/_as_gen/matplotlib.animation.AVConvWriter.rst:37:<autosummary>:1"
1014+
],
10121015
"matplotlib.animation.ArtistAnimation.new_frame_seq": [
10131016
"doc/api/_as_gen/matplotlib.animation.ArtistAnimation.rst:23:<autosummary>:1"
10141017
],
@@ -1070,7 +1073,7 @@
10701073
"doc/api/_as_gen/matplotlib.animation.FFMpegFileWriter.rst:28:<autosummary>:1"
10711074
],
10721075
"matplotlib.animation.FFMpegWriter.args_key": [
1073-
"doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:36:<autosummary>:1"
1076+
"doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:37:<autosummary>:1"
10741077
],
10751078
"matplotlib.animation.FFMpegWriter.bin_path": [
10761079
"doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:28:<autosummary>:1"
@@ -1079,13 +1082,13 @@
10791082
"doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:28:<autosummary>:1"
10801083
],
10811084
"matplotlib.animation.FFMpegWriter.exec_key": [
1082-
"doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:36:<autosummary>:1"
1085+
"doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:37:<autosummary>:1"
10831086
],
10841087
"matplotlib.animation.FFMpegWriter.finish": [
10851088
"doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:28:<autosummary>:1"
10861089
],
10871090
"matplotlib.animation.FFMpegWriter.frame_size": [
1088-
"doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:36:<autosummary>:1"
1091+
"doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:37:<autosummary>:1"
10891092
],
10901093
"matplotlib.animation.FFMpegWriter.grab_frame": [
10911094
"doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:28:<autosummary>:1"
@@ -1094,14 +1097,17 @@
10941097
"doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:28:<autosummary>:1"
10951098
],
10961099
"matplotlib.animation.FFMpegWriter.output_args": [
1097-
"doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:36:<autosummary>:1"
1100+
"doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:37:<autosummary>:1"
10981101
],
10991102
"matplotlib.animation.FFMpegWriter.saving": [
11001103
"doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:28:<autosummary>:1"
11011104
],
11021105
"matplotlib.animation.FFMpegWriter.setup": [
11031106
"doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:28:<autosummary>:1"
11041107
],
1108+
"matplotlib.animation.FFMpegWriter.supported_formats": [
1109+
"doc/api/_as_gen/matplotlib.animation.FFMpegWriter.rst:37:<autosummary>:1"
1110+
],
11051111
"matplotlib.animation.FileMovieWriter.args_key": [
11061112
"lib/matplotlib/animation.py:docstring of matplotlib.animation.FileMovieWriter.clear_temp:1:<autosummary>:1"
11071113
],
@@ -1123,6 +1129,9 @@
11231129
"matplotlib.animation.FileMovieWriter.saving": [
11241130
"doc/api/_as_gen/matplotlib.animation.FileMovieWriter.rst:28:<autosummary>:1"
11251131
],
1132+
"matplotlib.animation.FileMovieWriter.supported_formats": [
1133+
"lib/matplotlib/animation.py:docstring of matplotlib.animation.FileMovieWriter.clear_temp:1:<autosummary>:1"
1134+
],
11261135
"matplotlib.animation.FuncAnimation.pause": [
11271136
"lib/matplotlib/animation.py:docstring of matplotlib.animation.FuncAnimation.new_frame_seq:1:<autosummary>:1"
11281137
],
@@ -1202,7 +1211,7 @@
12021211
"doc/api/_as_gen/matplotlib.animation.ImageMagickFileWriter.rst:28:<autosummary>:1"
12031212
],
12041213
"matplotlib.animation.ImageMagickWriter.args_key": [
1205-
"doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:37:<autosummary>:1"
1214+
"doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:38:<autosummary>:1"
12061215
],
12071216
"matplotlib.animation.ImageMagickWriter.bin_path": [
12081217
"doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:28:<autosummary>:1"
@@ -1211,16 +1220,16 @@
12111220
"doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:28:<autosummary>:1"
12121221
],
12131222
"matplotlib.animation.ImageMagickWriter.delay": [
1214-
"doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:37:<autosummary>:1"
1223+
"doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:38:<autosummary>:1"
12151224
],
12161225
"matplotlib.animation.ImageMagickWriter.exec_key": [
1217-
"doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:37:<autosummary>:1"
1226+
"doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:38:<autosummary>:1"
12181227
],
12191228
"matplotlib.animation.ImageMagickWriter.finish": [
12201229
"doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:28:<autosummary>:1"
12211230
],
12221231
"matplotlib.animation.ImageMagickWriter.frame_size": [
1223-
"doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:37:<autosummary>:1"
1232+
"doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:38:<autosummary>:1"
12241233
],
12251234
"matplotlib.animation.ImageMagickWriter.grab_frame": [
12261235
"doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:28:<autosummary>:1"
@@ -1229,14 +1238,17 @@
12291238
"doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:28:<autosummary>:1"
12301239
],
12311240
"matplotlib.animation.ImageMagickWriter.output_args": [
1232-
"doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:37:<autosummary>:1"
1241+
"doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:38:<autosummary>:1"
12331242
],
12341243
"matplotlib.animation.ImageMagickWriter.saving": [
12351244
"doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:28:<autosummary>:1"
12361245
],
12371246
"matplotlib.animation.ImageMagickWriter.setup": [
12381247
"doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:28:<autosummary>:1"
12391248
],
1249+
"matplotlib.animation.ImageMagickWriter.supported_formats": [
1250+
"doc/api/_as_gen/matplotlib.animation.ImageMagickWriter.rst:38:<autosummary>:1"
1251+
],
12401252
"matplotlib.animation.MovieWriter.frame_size": [
12411253
"lib/matplotlib/animation.py:docstring of matplotlib.animation.MovieWriter.args_key:1:<autosummary>:1"
12421254
],

lib/matplotlib/animation.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import warnings
3232

3333
import numpy as np
34+
from PIL import Image
3435

3536
import matplotlib as mpl
3637
from matplotlib._animation_data import (
@@ -263,6 +264,10 @@ class MovieWriter(AbstractMovieWriter):
263264
exec_key = cbook._deprecate_privatize_attribute("3.3")
264265
args_key = cbook._deprecate_privatize_attribute("3.3")
265266

267+
# Pipe-based writers only support RGBA, but file-based ones support more
268+
# formats.
269+
supported_formats = ["rgba"]
270+
266271
def __init__(self, fps=5, codec=None, bitrate=None, extra_args=None,
267272
metadata=None):
268273
"""
@@ -296,8 +301,7 @@ def __init__(self, fps=5, codec=None, bitrate=None, extra_args=None,
296301

297302
super().__init__(fps=fps, metadata=metadata, codec=codec,
298303
bitrate=bitrate)
299-
300-
self.frame_format = 'rgba'
304+
self.frame_format = self.supported_formats[0]
301305
self.extra_args = extra_args
302306

303307
def _adjust_frame_size(self):
@@ -471,6 +475,10 @@ def frame_format(self, frame_format):
471475
if frame_format in self.supported_formats:
472476
self._frame_format = frame_format
473477
else:
478+
cbook._warn_external(
479+
f"Ignoring file format {frame_format!r} which is not "
480+
f"supported by {type(self).__name__}; using "
481+
f"{self.supported_formats[0]} instead.")
474482
self._frame_format = self.supported_formats[0]
475483

476484
def _base_temp_name(self):
@@ -521,7 +529,6 @@ def setup(self, fig, outfile, dpi=None):
521529
self._frames = []
522530

523531
def grab_frame(self, **savefig_kwargs):
524-
from PIL import Image
525532
buf = BytesIO()
526533
self.fig.savefig(
527534
buf, **{**savefig_kwargs, "format": "rgba", "dpi": self.dpi})
@@ -736,15 +743,18 @@ class ImageMagickFileWriter(ImageMagickBase, FileMovieWriter):
736743
737744
Frames are written to temporary files on disk and then stitched
738745
together at the end.
739-
740746
"""
741747

742748
supported_formats = ['png', 'jpeg', 'ppm', 'tiff', 'sgi', 'bmp',
743749
'pbm', 'raw', 'rgba']
744750

745751
def _args(self):
746-
return ([self.bin_path(), '-delay', str(self.delay), '-loop', '0',
747-
'%s*.%s' % (self.temp_prefix, self.frame_format)]
752+
# Force format: ImageMagick does not recognize 'raw'.
753+
fmt = 'rgba:' if self.frame_format == 'raw' else ''
754+
return ([self.bin_path(),
755+
'-size', '%ix%i' % self.frame_size, '-depth', '8',
756+
'-delay', str(self.delay), '-loop', '0',
757+
'%s%s*.%s' % (fmt, self.temp_prefix, self.frame_format)]
748758
+ self.output_args)
749759

750760

0 commit comments

Comments
 (0)