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

Skip to content

Commit 5ba3911

Browse files
authored
Simplification of animated histogram example (#18821)
* Simplification of animated histogram example Newly a BarContainer from hist() function is used. * Use compact style arguments.
1 parent 61a13c1 commit 5ba3911

File tree

1 file changed

+28
-64
lines changed

1 file changed

+28
-64
lines changed

examples/animation/animated_histogram.py

Lines changed: 28 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -3,89 +3,53 @@
33
Animated histogram
44
==================
55
6-
Use a path patch to draw a bunch of rectangles for an animated histogram.
6+
Use histogram's `.BarContainer` to draw a bunch of rectangles for an animated
7+
histogram.
78
"""
89

910
import numpy as np
1011

1112
import matplotlib.pyplot as plt
12-
import matplotlib.patches as patches
13-
import matplotlib.path as path
1413
import matplotlib.animation as animation
1514

1615
# Fixing random state for reproducibility
1716
np.random.seed(19680801)
17+
# Fixing bin edges
18+
HIST_BINS = np.linspace(-4, 4, 100)
1819

1920
# histogram our data with numpy
2021
data = np.random.randn(1000)
21-
n, bins = np.histogram(data, 100)
22-
23-
# get the corners of the rectangles for the histogram
24-
left = bins[:-1]
25-
right = bins[1:]
26-
bottom = np.zeros(len(left))
27-
top = bottom + n
28-
nrects = len(left)
29-
30-
###############################################################################
31-
# Here comes the tricky part -- we have to set up the vertex and path codes
32-
# arrays using `.Path.MOVETO`, `.Path.LINETO` and `.Path.CLOSEPOLY` for each
33-
# rect.
34-
#
35-
# * We need 1 ``MOVETO`` per rectangle, which sets the initial point.
36-
# * We need 3 ``LINETO``'s, which tell Matplotlib to draw lines from
37-
# vertex 1 to vertex 2, v2 to v3, and v3 to v4.
38-
# * We then need one ``CLOSEPOLY`` which tells Matplotlib to draw a line from
39-
# the v4 to our initial vertex (the ``MOVETO`` vertex), in order to close the
40-
# polygon.
41-
#
42-
# .. note::
43-
#
44-
# The vertex for ``CLOSEPOLY`` is ignored, but we still need a placeholder
45-
# in the ``verts`` array to keep the codes aligned with the vertices.
46-
nverts = nrects * (1 + 3 + 1)
47-
verts = np.zeros((nverts, 2))
48-
codes = np.full(nverts, path.Path.LINETO)
49-
codes[0::5] = path.Path.MOVETO
50-
codes[4::5] = path.Path.CLOSEPOLY
51-
verts[0::5, 0] = left
52-
verts[0::5, 1] = bottom
53-
verts[1::5, 0] = left
54-
verts[1::5, 1] = top
55-
verts[2::5, 0] = right
56-
verts[2::5, 1] = top
57-
verts[3::5, 0] = right
58-
verts[3::5, 1] = bottom
22+
n, _ = np.histogram(data, HIST_BINS)
5923

6024
###############################################################################
6125
# To animate the histogram, we need an ``animate`` function, which generates
62-
# a random set of numbers and updates the locations of the vertices for the
63-
# histogram (in this case, only the heights of each rectangle). ``patch`` will
64-
# eventually be a `.Patch` object.
65-
patch = None
26+
# a random set of numbers and updates the heights of rectanges. We utilize a
27+
# python closure to track an instance of `.BarContainer` whose `.Rectangle`
28+
# patches we shall update.
6629

6730

68-
def animate(i):
69-
# simulate new data coming in
70-
data = np.random.randn(1000)
71-
n, bins = np.histogram(data, 100)
72-
top = bottom + n
73-
verts[1::5, 1] = top
74-
verts[2::5, 1] = top
75-
return [patch, ]
31+
def prepare_animation(bar_container):
32+
33+
def animate(frame_number):
34+
# simulate new data coming in
35+
data = np.random.randn(1000)
36+
n, _ = np.histogram(data, HIST_BINS)
37+
for count, rect in zip(n, bar_container.patches):
38+
rect.set_height(count)
39+
return bar_container.patches
40+
return animate
7641

7742
###############################################################################
78-
# And now we build the `.Path` and `.Patch` instances for the histogram using
79-
# our vertices and codes. We add the patch to the `~.axes.Axes` instance, and
80-
# setup the `.FuncAnimation` with our ``animate`` function.
81-
fig, ax = plt.subplots()
82-
barpath = path.Path(verts, codes)
83-
patch = patches.PathPatch(
84-
barpath, facecolor='green', edgecolor='yellow', alpha=0.5)
85-
ax.add_patch(patch)
43+
# Using :func:`~matplotlib.pyplot.hist` allows us to get an instance of
44+
# `.BarContainer`, which is a collection of `.Rectangle` instances. Calling
45+
# ``prepare_animation`` will define ``animate`` function working with supplied
46+
# `.BarContainer`, all this is used to setup `.FuncAnimation`.
8647

87-
ax.set_xlim(left[0], right[-1])
88-
ax.set_ylim(bottom.min(), top.max())
48+
fig, ax = plt.subplots()
49+
_, _, bar_container = ax.hist(data, HIST_BINS, lw=1,
50+
ec="yellow", fc="green", alpha=0.5)
51+
ax.set_ylim(top=55) # set safe limit to ensure that all data is visible.
8952

90-
ani = animation.FuncAnimation(fig, animate, 50, repeat=False, blit=True)
53+
ani = animation.FuncAnimation(fig, prepare_animation(bar_container), 50,
54+
repeat=False, blit=True)
9155
plt.show()

0 commit comments

Comments
 (0)