简体   繁体   中英

How to plot an histogram or bar animation with matplotlib ArtistAnimation?

I'm trying to create histogram animation that stacks up samples one by one. I thought the following code would work, but it doesn't.

import matplotlib.pyplot as plt
from matplotlib.animation import ArtistAnimation

ims = []
fig = plt.figure()
x =[1,2,3,3,4,5,5,5,5,6,7,8,9,9,9,9,9,10]

for i in range(len(x)):
    img = plt.hist(x[:i])
    ims.append(img)

ani = ArtistAnimation(fig, ims, interval=100)
plt.show()

Changing plt.hist to plt.plot shows animation. Don't know what the difference is.

Thanks for reading.

plt.hist does not return an artist but a tuple with binning results and the artist (see here ).

This is also discussed in this thread in the Matplotlib mailing list:

ArtistAnimation expects to be given a list of lists (or tuples), where the inner collection contains all of the artists that should be rendered for a given frame. In the case of bar, it returns a BarCollection object (which I just learned), is a subclass of tuple. This explains why it works (by itself), when directly appended to the list given to ArtistAnimation; the BarCollection acts as the collection of artists that ArtistAnimation is expecting. In the case of the second example, ArtistAnimation is being given a list([BarCollection, Image]); because BarCollection isn't actually an Artist, it causes the problem.

The problem mentioned there uses different plot types:

im1 = ax1.imshow(f(xm, ym), aspect='equal', animated=True)
im2 = ax2.bar(xx, a, width=0.9*(b[1]-b[0]), color='C1')

and the solution in that case is

ims.append([im1] + list(im2))

The way to make this work in your case is to look at the return values of plt.hist and find out where the artists are being returned and put them in the correct list of lists format.

This works:

import matplotlib.animation as animation

fig = plt.figure()

# ims is a list of lists, each row is a list of artists to draw in the
# current frame; here we are just animating one artist, the image, in
# each frame
ims = []

for i in range(60):

    # hist returns a tuple with two binning results and then the artist (patches)
    n, bins, patches = plt.hist((np.random.rand(10),))

    # since patches is already a list we can just append it
    ims.append(patches)

ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True,
    repeat_delay=1000,)

plt.show()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM