From c8d1f6ed6a620eea02ea3c206d600a6a1e61bd10 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Tue, 28 Jul 2020 23:14:18 -0400 Subject: [PATCH] Backport PR #18093: Improve saving animated GIF with ffmpeg --- lib/matplotlib/animation.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/animation.py b/lib/matplotlib/animation.py index a30675fd1271..2568d455de39 100644 --- a/lib/matplotlib/animation.py +++ b/lib/matplotlib/animation.py @@ -310,7 +310,8 @@ def __init__(self, fps=5, codec=None, bitrate=None, extra_args=None, 'MovieWriter cannot be instantiated directly. Please use one ' 'of its subclasses.') - super().__init__(fps=fps, metadata=metadata) + super().__init__(fps=fps, metadata=metadata, codec=codec, + bitrate=bitrate) self.frame_format = 'rgba' self.extra_args = extra_args @@ -571,7 +572,9 @@ class FFMpegBase: @property def output_args(self): args = [] - if not Path(self.outfile).suffix == '.gif': + if Path(self.outfile).suffix == '.gif': + self.codec = 'gif' + else: args.extend(['-vcodec', self.codec]) extra_args = (self.extra_args if self.extra_args is not None else mpl.rcParams[self._args_key]) @@ -581,6 +584,11 @@ def output_args(self): # OSX). Also fixes internet explorer. This is as of 2015/10/29. if self.codec == 'h264' and '-pix_fmt' not in extra_args: args.extend(['-pix_fmt', 'yuv420p']) + # For GIF, we're telling FFMPEG to split the video stream, to generate + # a palette, and then use it for encoding. + elif self.codec == 'gif' and '-filter_complex' not in extra_args: + args.extend(['-filter_complex', + 'split [a][b];[a] palettegen [p];[b][p] paletteuse']) if self.bitrate > 0: args.extend(['-b', '%dk' % self.bitrate]) # %dk: bitrate in kbps. args.extend(extra_args)