Looping over subplots in animation

Viewed 141

I am trying to simultaneously plot four animations in matplotlib subplots. Here's the data:

x1 = np.random.normal(-2.5, 1, 10000)
x2 = np.random.gamma(2, 1.5, 10000)
x3 = np.random.exponential(2, 10000)+7
x4 = np.random.uniform(14,20, 10000)
xs=[x1,x2,x3,x4]
bins=[np.linspace(-6,1, num=21),np.linspace(0,15, num=21),np.linspace(7,20, num=21),np.linspace(14,20, num=21)]

Now, I tried out a few methods. This one works perfectly fine:

def update1(curr):
    if curr==10000:
        ani.event_source.stop()
    for ax in axs:
        ax.cla()
    axs[0].hist(xs[0][:curr], bins=bins[0], normed=True)
    axs[1].hist(xs[1][:curr], bins=bins[1], normed=True)
    axs[2].hist(xs[2][:curr], bins=bins[2], normed=True)
    axs[3].hist(xs[3][:curr], bins=bins[3], normed=True)
fig, ((ax1,ax2),(ax3,ax4))=plt.subplots(2,2, sharex=True)
axs=[ax1,ax2,ax3,ax4]
ani=animation.FuncAnimation(fig, update1,interval=50)

But strangely enough, this one doesn't:

def update2(curr):
    if curr==10000:
        ani.event_source.stop()
    for i in range(len(axs)):
        axs[i].cla()
    for i in range(len(axs)):
        x=xs[i]
        axs[i].hist(x[:curr], bins=bins[i], normed=True)
fig, ((ax1,ax2),(ax3,ax4))=plt.subplots(2,2, sharex=True)
axs=[ax1,ax2,ax3,ax4]
ani=animation.FuncAnimation(fig, update2,interval=50)

This just draws the figure and axes but does not fill in the histograms. I know that it works outside the animation (I tried). Could someone explain what's going on? I've had a look at these:

Plotting multiple subplot animations

Animation of histograms in subplot

The first one seems to be dud and while the second one works, my initial query hasn't been resolved.

1 Answers

Using python 3.8-dev with matplotlib==3.2.2 and numpy==1.19.0, your code worked fine for me. Here is the entire script that worked fine for me:

from matplotlib import numpy as np
from matplotlib import animation
from matplotlib import pyplot as plt

x1 = np.random.normal(-2.5, 1, 10000)
x2 = np.random.gamma(2, 1.5, 10000)
x3 = np.random.exponential(2, 10000)+7
x4 = np.random.uniform(14,20, 10000)
xs=[x1,x2,x3,x4]
bins=[
    np.linspace(-6,1, num=21),
    np.linspace(0,15, num=21),
    np.linspace(7,20, num=21),
    np.linspace(14, 20, num=21)
]


def update1(curr):
    if curr==10000:
        ani.event_source.stop()
    for ax in axs:
        ax.cla()
    axs[0].hist(xs[0][:curr], bins=bins[0], normed=True)
    axs[1].hist(xs[1][:curr], bins=bins[1], normed=True)
    axs[2].hist(xs[2][:curr], bins=bins[2], normed=True)
    axs[3].hist(xs[3][:curr], bins=bins[3], normed=True)
fig, ((ax1,ax2),(ax3,ax4))=plt.subplots(2,2, sharex=True)
axs=[ax1,ax2,ax3,ax4]
ani = animation.FuncAnimation(fig, update1, interval=50)
plt.show()


def update2(curr):
    if curr==10000:
        ani.event_source.stop()
    for i in range(len(axs)):
        axs[i].cla()
    for i in range(len(axs)):
        x=xs[i]
        axs[i].hist(x[:curr], bins=bins[i], normed=True)
fig, ((ax1,ax2),(ax3,ax4))=plt.subplots(2,2, sharex=True)
axs=[ax1,ax2,ax3,ax4]
ani=animation.FuncAnimation(fig, update2,interval=50)
plt.show()

The only real difference is that I had to take out the normed=True parts, which were causing an error:

AttributeError: 'Rectangle' object has no property 'normed'

I know this isn't an answer but I cannot reproduce the OP problem so I am posting something that works.

Related