From b953a82bc52179a4e80701cf276070f4a7f252f4 Mon Sep 17 00:00:00 2001 From: Tyler Makaro Date: Fri, 27 Jul 2018 22:25:42 -0700 Subject: [PATCH 1/8] add loop kwarg to PillowWriter Adds an optional parameter to PillowWriter that will set the number of times that a gif should loop for. Defaults to 0 meaning endless --- lib/matplotlib/animation.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/animation.py b/lib/matplotlib/animation.py index f33a0a56b03a..bfa48f66f724 100644 --- a/lib/matplotlib/animation.py +++ b/lib/matplotlib/animation.py @@ -553,6 +553,7 @@ def isAvailable(cls): def __init__(self, *args, **kwargs): if kwargs.get("extra_args") is None: kwargs["extra_args"] = () + self.loop = kwargs.pop("loop", 0) super().__init__(*args, **kwargs) def setup(self, fig, outfile, dpi=None): @@ -576,7 +577,7 @@ def grab_frame(self, **savefig_kwargs): def finish(self): self._frames[0].save( self._outfile, save_all=True, append_images=self._frames[1:], - duration=int(1000 / self.fps)) + duration=int(1000 / self.fps), loop=self.loop) # Base class of ffmpeg information. Has the config keys and the common set From 43e1a7f089c917862bef584b1584fcca30af1b13 Mon Sep 17 00:00:00 2001 From: Tyler Makaro Date: Sat, 28 Jul 2018 10:09:04 -0700 Subject: [PATCH 2/8] next_whats_new file for endless gifs --- doc/users/next_whats_new/endless_gif.rst | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 doc/users/next_whats_new/endless_gif.rst diff --git a/doc/users/next_whats_new/endless_gif.rst b/doc/users/next_whats_new/endless_gif.rst new file mode 100644 index 000000000000..825dd24725b4 --- /dev/null +++ b/doc/users/next_whats_new/endless_gif.rst @@ -0,0 +1,7 @@ +Looping GIFs with PillowWriter +------------------------------ + +We acknowledge that most people want to watch a gif more than once. Saving an animatation +as a gif with PillowWriter now defaults to producing an endless looping gif. Gifs can be set +to loop a finite number of times by passing the ``loop`` keyword argument to PillowWriter. +To restore the old behaviour of not looping use ``PillowWriter(loop=1)`` From fe8771197c95ab10cd43f2cd6c276e0a7a80c37a Mon Sep 17 00:00:00 2001 From: Tyler Makaro Date: Sat, 28 Jul 2018 11:53:37 -0700 Subject: [PATCH 3/8] adjust PillowWriter loop kwarg --- lib/matplotlib/animation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/animation.py b/lib/matplotlib/animation.py index bfa48f66f724..f2f094f13872 100644 --- a/lib/matplotlib/animation.py +++ b/lib/matplotlib/animation.py @@ -550,10 +550,10 @@ def isAvailable(cls): return False return True - def __init__(self, *args, **kwargs): + def __init__(self, *args, loop=0, **kwargs): + self.loop = loop if kwargs.get("extra_args") is None: kwargs["extra_args"] = () - self.loop = kwargs.pop("loop", 0) super().__init__(*args, **kwargs) def setup(self, fig, outfile, dpi=None): From be2e2af5fce3bdccb675e08f1af92e3bad0f0274 Mon Sep 17 00:00:00 2001 From: Tyler Makaro Date: Sat, 28 Jul 2018 12:33:37 -0700 Subject: [PATCH 4/8] add docstring to PillowWriter --- lib/matplotlib/animation.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/lib/matplotlib/animation.py b/lib/matplotlib/animation.py index f2f094f13872..aef8e0f7b1a2 100644 --- a/lib/matplotlib/animation.py +++ b/lib/matplotlib/animation.py @@ -551,6 +551,33 @@ def isAvailable(cls): return True def __init__(self, *args, loop=0, **kwargs): + '''PillowWriter + + Parameters + ---------- + fps: int + Framerate for the gif. + loop: int + The number of times that the gif will loop. + A value of 0 is endless. + codec: string or None, optional + The codec to use. If ``None`` (the default) the ``animation.codec`` + rcParam is used. + bitrate: int or None, optional + The bitrate for the saved movie file, which is one way to control + the output file size and quality. The default value is ``None``, + which uses the ``animation.bitrate`` rcParam. A value of -1 + implies that the bitrate should be determined automatically by the + underlying utility. + extra_args: list of strings or None, optional + A list of extra string arguments to be passed to the underlying + movie utility. The default is ``None``, which passes the additional + arguments in the ``animation.extra_args`` rcParam. + metadata: Dict[str, str] or None + A dictionary of keys and values for metadata to include in the + output file. Some keys that may be of use include: + title, artist, genre, subject, copyright, srcform, comment. + ''' self.loop = loop if kwargs.get("extra_args") is None: kwargs["extra_args"] = () From dae6ea6d069311be9b83626fc2a995177bebfede Mon Sep 17 00:00:00 2001 From: Tyler Makaro Date: Sat, 28 Jul 2018 14:13:13 -0700 Subject: [PATCH 5/8] ValueError if loop is not an int in PillowWriter --- lib/matplotlib/animation.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/animation.py b/lib/matplotlib/animation.py index aef8e0f7b1a2..6a542a15e04b 100644 --- a/lib/matplotlib/animation.py +++ b/lib/matplotlib/animation.py @@ -578,7 +578,10 @@ def __init__(self, *args, loop=0, **kwargs): output file. Some keys that may be of use include: title, artist, genre, subject, copyright, srcform, comment. ''' - self.loop = loop + if type(loop) == int: + self.loop = loop + else: + raise ValueError("loop must be an int") if kwargs.get("extra_args") is None: kwargs["extra_args"] = () super().__init__(*args, **kwargs) From 5484bc7d82ad726b5256efeaeaf401c233c376f3 Mon Sep 17 00:00:00 2001 From: Tyler Makaro Date: Tue, 18 Sep 2018 16:02:54 -0700 Subject: [PATCH 6/8] remove API changes --- doc/users/next_whats_new/endless_gif.rst | 10 ++++----- lib/matplotlib/animation.py | 28 ++---------------------- 2 files changed, 7 insertions(+), 31 deletions(-) diff --git a/doc/users/next_whats_new/endless_gif.rst b/doc/users/next_whats_new/endless_gif.rst index 825dd24725b4..ad649c7c4af8 100644 --- a/doc/users/next_whats_new/endless_gif.rst +++ b/doc/users/next_whats_new/endless_gif.rst @@ -1,7 +1,7 @@ -Looping GIFs with PillowWriter ------------------------------- +:orphan: + +Endless Looping GIFs with PillowWriter +-------------------------------------- We acknowledge that most people want to watch a gif more than once. Saving an animatation -as a gif with PillowWriter now defaults to producing an endless looping gif. Gifs can be set -to loop a finite number of times by passing the ``loop`` keyword argument to PillowWriter. -To restore the old behaviour of not looping use ``PillowWriter(loop=1)`` +as a gif with PillowWriter now produces an endless looping gif. diff --git a/lib/matplotlib/animation.py b/lib/matplotlib/animation.py index 6a542a15e04b..fc9b0c936843 100644 --- a/lib/matplotlib/animation.py +++ b/lib/matplotlib/animation.py @@ -550,38 +550,14 @@ def isAvailable(cls): return False return True - def __init__(self, *args, loop=0, **kwargs): + def __init__(self, *args, **kwargs): '''PillowWriter Parameters ---------- fps: int Framerate for the gif. - loop: int - The number of times that the gif will loop. - A value of 0 is endless. - codec: string or None, optional - The codec to use. If ``None`` (the default) the ``animation.codec`` - rcParam is used. - bitrate: int or None, optional - The bitrate for the saved movie file, which is one way to control - the output file size and quality. The default value is ``None``, - which uses the ``animation.bitrate`` rcParam. A value of -1 - implies that the bitrate should be determined automatically by the - underlying utility. - extra_args: list of strings or None, optional - A list of extra string arguments to be passed to the underlying - movie utility. The default is ``None``, which passes the additional - arguments in the ``animation.extra_args`` rcParam. - metadata: Dict[str, str] or None - A dictionary of keys and values for metadata to include in the - output file. Some keys that may be of use include: - title, artist, genre, subject, copyright, srcform, comment. ''' - if type(loop) == int: - self.loop = loop - else: - raise ValueError("loop must be an int") if kwargs.get("extra_args") is None: kwargs["extra_args"] = () super().__init__(*args, **kwargs) @@ -607,7 +583,7 @@ def grab_frame(self, **savefig_kwargs): def finish(self): self._frames[0].save( self._outfile, save_all=True, append_images=self._frames[1:], - duration=int(1000 / self.fps), loop=self.loop) + duration=int(1000 / self.fps), loop=0) # Base class of ffmpeg information. Has the config keys and the common set From 2dc2c99f381e02d51ce6f692ff9a8aa654b682d6 Mon Sep 17 00:00:00 2001 From: Tyler Makaro Date: Wed, 19 Sep 2018 09:34:27 -0700 Subject: [PATCH 7/8] fix typo --- doc/users/next_whats_new/endless_gif.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/users/next_whats_new/endless_gif.rst b/doc/users/next_whats_new/endless_gif.rst index ad649c7c4af8..0561f698c0b4 100644 --- a/doc/users/next_whats_new/endless_gif.rst +++ b/doc/users/next_whats_new/endless_gif.rst @@ -3,5 +3,5 @@ Endless Looping GIFs with PillowWriter -------------------------------------- -We acknowledge that most people want to watch a gif more than once. Saving an animatation +We acknowledge that most people want to watch a gif more than once. Saving an animation as a gif with PillowWriter now produces an endless looping gif. From 50568c7b6d2d578dfb7f9aa303df506fde434cf1 Mon Sep 17 00:00:00 2001 From: Tyler Makaro Date: Wed, 19 Sep 2018 09:43:09 -0700 Subject: [PATCH 8/8] kill docstring for now --- lib/matplotlib/animation.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/matplotlib/animation.py b/lib/matplotlib/animation.py index fc9b0c936843..1fa62a8d805d 100644 --- a/lib/matplotlib/animation.py +++ b/lib/matplotlib/animation.py @@ -551,13 +551,6 @@ def isAvailable(cls): return True def __init__(self, *args, **kwargs): - '''PillowWriter - - Parameters - ---------- - fps: int - Framerate for the gif. - ''' if kwargs.get("extra_args") is None: kwargs["extra_args"] = () super().__init__(*args, **kwargs)