Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit bbe4fd8

Browse filesBrowse files
committed
Merge remote-tracking branch 'matplotlib/v2.x'
Conflicts: lib/matplotlib/animation.py - had to merge documentation changes with an ABC being pulled out the top of MovieWriter lib/matplotlib/font_manager.py - whitespace conflicts
2 parents e26db3a + f367003 commit bbe4fd8
Copy full SHA for bbe4fd8

File tree

Expand file treeCollapse file tree

10 files changed

+846
-287
lines changed
Filter options
Expand file treeCollapse file tree

10 files changed

+846
-287
lines changed

‎doc/api/animation_api.rst

Copy file name to clipboard
+330-9Lines changed: 330 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,333 @@
1-
*********
2-
animation
3-
*********
1+
======================
2+
``animation`` module
3+
======================
44

5+
.. automodule:: matplotlib.animation
56

6-
:mod:`matplotlib.animation`
7-
===========================
7+
.. contents:: Table of Contents
8+
:depth: 1
9+
:local:
10+
:backlinks: entry
811

9-
.. automodule:: matplotlib.animation
10-
:members:
11-
:undoc-members:
12-
:show-inheritance:
12+
13+
Animation
14+
=========
15+
16+
The easiest way to make a live animation in matplotlib is to use one of the
17+
`Animation` classes.
18+
19+
.. autosummary::
20+
:toctree: _as_gen
21+
:nosignatures:
22+
23+
FuncAnimation
24+
ArtistAnimation
25+
26+
In both cases it is critical to keep a reference to the instance
27+
object. The animation is advanced by a timer (typically from the host
28+
GUI framework) which the `Animation` object holds the only reference
29+
to. If you do not hold a reference to the `Animation` object, it (and
30+
hence the timers), will be garbage collected which will stop the
31+
animation.
32+
33+
To save an animation to disk use
34+
35+
.. autosummary::
36+
:toctree: _as_gen
37+
:nosignatures:
38+
39+
Animation.save
40+
Animation.to_html5_video
41+
42+
See :ref:`ani_writer_classes` below for details about what movie formats are supported.
43+
44+
45+
``FuncAnimation``
46+
-----------------
47+
48+
The inner workings of `FuncAnimation` is more-or-less::
49+
50+
for d in frames:
51+
artists = func(d, *fargs)
52+
fig.canvas.draw_idle()
53+
plt.pause(interval)
54+
55+
56+
with details to handle 'blitting' (to dramatically improve the live
57+
performance), to be non-blocking, handle repeats, multiple animated
58+
axes, and easily save the animation to a movie file.
59+
60+
'Blitting' is a `old technique
61+
<https://en.wikipedia.org/wiki/Bit_blit>`__ in computer graphics. The
62+
general gist is to take an existing bit map (in our case a mostly
63+
rasterized figure) and then 'blit' one more artist on top. Thus, by
64+
managing a saved 'clean' bitmap, we can only re-draw the few artists
65+
that are changing at each frame and possibly save significant amounts of
66+
time. When using blitting (by passing ``blit=True``) the core loop of
67+
`FuncAnimation` gets a bit more complicated ::
68+
69+
ax = fig.gca()
70+
71+
def update_blit(artists):
72+
fig.canvas.restore_region(bg_cache)
73+
for a in artists:
74+
a.axes.draw_artist(a)
75+
76+
ax.figure.canvas.blit(ax.bbox)
77+
78+
artists = init_func()
79+
80+
for a in artists:
81+
a.set_animated(True)
82+
83+
fig.canvas.draw()
84+
bg_cache = fig.canvas.copy_from_bbox(ax.bbox)
85+
86+
for f in frames:
87+
artists = func(f, *fargs)
88+
update_blit(artists)
89+
plt.pause(interval)
90+
91+
This is of course leaving out many details (such as updating the
92+
background when the figure is resized or fully re-drawn). However,
93+
this hopefully minimalist example gives a sense of how ``init_func``
94+
and ``func`` are used inside of `FuncAnimation` and the theory of how
95+
'blitting' works.
96+
97+
The expected signature on ``func`` and ``init_func`` is very simple to
98+
keep `FuncAnimation` out of your book keeping and plotting logic, but
99+
this means that the callable objects you pass in must know what
100+
artists they should be working on. There are several approaches to
101+
handling this, of varying complexity and encapsulation. The simplest
102+
approach, which works quite well in the case of a script, is to define the
103+
artist at a global scope and let Python sort things out. For example ::
104+
105+
import numpy as np
106+
import matplotlib.pyplot as plt
107+
from matplotlib.animation import FuncAnimation
108+
109+
fig, ax = plt.subplots()
110+
xdata, ydata = [], []
111+
ln, = plt.plot([], [], 'ro', animated=True)
112+
113+
def init():
114+
ax.set_xlim(0, 2*np.pi)
115+
ax.set_ylim(-1, 1)
116+
return ln,
117+
118+
def update(frame):
119+
xdata.append(frame)
120+
ydata.append(np.sin(frame))
121+
ln.set_data(xdata, ydata)
122+
return ln,
123+
124+
ani = FuncAnimation(fig, update, frames=np.linspace(0, 2*np.pi, 128),
125+
init_func=init, blit=True)
126+
plt.show()
127+
128+
129+
The second method is to us `functools.partial` to 'bind' artists to
130+
function. A third method is to use closures to build up the required
131+
artists and functions. A fourth method is to create a class.
132+
133+
134+
135+
136+
Examples
137+
~~~~~~~~
138+
139+
.. toctree::
140+
:maxdepth: 1
141+
142+
../examples/animation/animate_decay
143+
../examples/animation/bayes_update
144+
../examples/animation/double_pendulum_animated
145+
../examples/animation/dynamic_image
146+
../examples/animation/histogram
147+
../examples/animation/rain
148+
../examples/animation/random_data
149+
../examples/animation/simple_3danim
150+
../examples/animation/simple_anim
151+
../examples/animation/strip_chart_demo
152+
../examples/animation/unchained
153+
154+
``ArtistAnimation``
155+
-------------------
156+
157+
158+
Examples
159+
~~~~~~~~
160+
161+
.. toctree::
162+
:maxdepth: 1
163+
164+
../examples/animation/basic_example
165+
../examples/animation/basic_example_writer
166+
../examples/animation/dynamic_image2
167+
168+
169+
170+
171+
Writer Classes
172+
==============
173+
174+
175+
176+
The provided writers fall into two broad categories: pipe-based and
177+
file-based. The pipe-based writers stream the captured frames over a
178+
pipe to an external process. The pipe-based variants tend to be more
179+
performant, but may not work on all systems.
180+
181+
.. autosummary::
182+
:toctree: _as_gen
183+
:nosignatures:
184+
185+
186+
FFMpegWriter
187+
ImageMagickFileWriter
188+
AVConvWriter
189+
190+
Alternatively the file-based writers save temporary files for each
191+
frame which are stitched into a single file at the end. Although
192+
slower, these writers can be easier to debug.
193+
194+
.. autosummary::
195+
:toctree: _as_gen
196+
:nosignatures:
197+
198+
FFMpegFileWriter
199+
ImageMagickWriter
200+
AVConvFileWriter
201+
202+
203+
Fundamentally, a `MovieWriter` provides a way to grab sequential frames
204+
from the same underlying `~matplotlib.figure.Figure` object. The base
205+
class `MovieWriter` implements 3 methods and a context manager. The
206+
only difference between the pipe-based and file-based writers is in the
207+
arguments to their respective ``setup`` methods.
208+
209+
210+
.. autosummary::
211+
:toctree: _as_gen
212+
:nosignatures:
213+
214+
MovieWriter.setup
215+
FileMovieWriter.setup
216+
MovieWriter.grab_frame
217+
MovieWriter.finish
218+
MovieWriter.saving
219+
220+
221+
The ``setup()`` method is used to prepare the writer (possibly opening
222+
a pipe), successive calls to ``grab_frame()`` capture a single frame
223+
at a time and ``finish()`` finalizes the movie and writes the output
224+
file to disk. For example ::
225+
226+
moviewriter = MovieWriter(...)
227+
moviewriter.setup(fig=fig, 'my_movie.ext', dpi=100)
228+
for j in range(n):
229+
update_figure(n)
230+
moviewriter.grab_frame()
231+
moviewriter.finish()
232+
233+
234+
If using the writer classes directly (not through `Animation.save`), it is strongly encouraged
235+
to use the `~MovieWriter.saving` context manager ::
236+
237+
with moviewriter.saving(fig, 'myfile.mp4', dpi=100):
238+
for j in range(n):
239+
update_figure(n)
240+
moviewriter.grab_frame()
241+
242+
243+
to ensures that setup and cleanup are performed as necessary.
244+
245+
246+
:ref:`animation-moviewriter`
247+
248+
249+
.. _ani_writer_classes:
250+
251+
Helper Classes
252+
==============
253+
254+
255+
Animation Base Classes
256+
----------------------
257+
258+
259+
.. autosummary::
260+
:toctree: _as_gen
261+
:nosignatures:
262+
263+
Animation
264+
TimedAnimation
265+
266+
267+
Custom Animation classes
268+
------------------------
269+
270+
:ref:`animation-subplots`
271+
272+
Writer Registry
273+
---------------
274+
275+
A module-level registry is provided to map between the name of the
276+
writer and the class to allow a string to be passed to
277+
`Animation.save` instead of a writer instance.
278+
279+
.. autosummary::
280+
:toctree: _as_gen
281+
:nosignatures:
282+
283+
MovieWriterRegistry
284+
285+
Writer Base Classes
286+
-------------------
287+
288+
To reduce code duplication base classes
289+
290+
.. autosummary::
291+
:toctree: _as_gen
292+
:nosignatures:
293+
294+
AbstractMovieWriter
295+
MovieWriter
296+
FileMovieWriter
297+
298+
and mixins are provided
299+
300+
.. autosummary::
301+
:toctree: _as_gen
302+
:nosignatures:
303+
304+
AVConvBase
305+
FFMpegBase
306+
ImageMagickBase
307+
308+
See the source code for how to easily implement new `MovieWriter`
309+
classes.
310+
311+
312+
Inheritance Diagrams
313+
====================
314+
315+
.. inheritance-diagram:: matplotlib.animation.FuncAnimation matplotlib.animation.ArtistAnimation
316+
:private-bases:
317+
318+
.. inheritance-diagram:: matplotlib.animation.AVConvFileWriter matplotlib.animation.AVConvWriter matplotlib.animation.FFMpegFileWriter matplotlib.animation.FFMpegWriter matplotlib.animation.ImageMagickFileWriter matplotlib.animation.ImageMagickWriter
319+
:private-bases:
320+
321+
322+
323+
Deprecated
324+
==========
325+
326+
327+
.. autosummary::
328+
:toctree: _as_gen
329+
:nosignatures:
330+
331+
MencoderBase
332+
MencoderFileWriter
333+
MencoderWriter

‎doc/api/api_changes.rst

Copy file name to clipboardExpand all lines: doc/api/api_changes.rst
+5-2Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ the kwarg is None which internally sets it to the 'auto' string,
141141
triggering a new algorithm for adjusting the maximum according
142142
to the axis length relative to the ticklabel font size.
143143

144-
`matplotlib.ticker.LogFormatter` gains minor_thresholds kwarg
145-
-------------------------------------------------------------
144+
`matplotlib.ticker.LogFormatter`: two new kwargs
145+
------------------------------------------------
146146

147147
Previously, minor ticks on log-scaled axes were not labeled by
148148
default. An algorithm has been added to the
@@ -151,6 +151,9 @@ ticks between integer powers of the base. The algorithm uses
151151
two parameters supplied in a kwarg tuple named 'minor_thresholds'.
152152
See the docstring for further explanation.
153153

154+
To improve support for axes using `~matplotlib.ticker.SymmetricLogLocator`,
155+
a 'linthresh' kwarg was added.
156+
154157

155158
New defaults for 3D quiver function in mpl_toolkits.mplot3d.axes3d.py
156159
---------------------------------------------------------------------

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.