Reputation: 2171
I have the following animated subplots that simulate histograms of four different distributions:
import numpy
from matplotlib.pylab import *
import matplotlib.animation as animation
n = 100
# generate 4 random variables from the random, gamma, exponential, and uniform distributions
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)
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
def updateData(curr):
if curr == n:
a.event_source.stop()
ax1.hist(x1[:curr], normed=True, bins=20, alpha=0.5)
ax2.hist(x2[:curr], normed=True, bins=20, alpha=0.5)
ax3.hist(x3[:curr], normed=True, bins=20, alpha=0.5)
ax4.hist(x4[:curr], normed=True, bins=20, alpha=0.5)
simulation = animation.FuncAnimation(fig, updateData, interval=20, repeat=False)
plt.show()
It works, but for some reason the normed=True is being ignored for the y-axis scaling. If I take these plots out of the animation, they scale properly. How do I get proper scaling in the animation?
EDIT
Instead of having a scale like this (outside of animation):
Upvotes: 2
Views: 5647
Reputation: 36
Yeah!! I also faced the same problem, if you are getting such kind of problem don't forget to clear the axis before displaying each frame of the animation.
use
plt.cla()
or
ax.clear()
(in your case)
for each axis
before doing the plot in the function defined for animation
Upvotes: 1
Reputation: 339430
The normed = True
argument to the histogram makes the histogram plot the density of the distribution. From the documentation:
normed : boolean, optional
If True, the first element of the return tuple will be the counts normalized to form a probability density, i.e., n/(len(x)`dbin), i.e., the integral of the histogram will sum to 1. If stacked is also True, the sum of the histograms is normalized to 1. Default is False
This means that the hight of the histogram bar depends on the bin width. If only one data point is plotted as is the case at the beginning of the animation the bar height will be 1./binwidth. If the bin width is smaller than zero, the bar height might become very large.
It's therefore a good idea to fix the bins and use them throughout the animation.
It's also reasonable to clear the axes such that there are not 100 different histograms being plotted.
import numpy as np
from matplotlib.pylab import *
import matplotlib.animation as animation
# generate 4 random variables from the random, gamma, exponential, and uniform distribution
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)
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
def updateData(curr):
if curr <=2: return
for ax in (ax1, ax2, ax3, ax4):
ax.clear()
ax1.hist(x1[:curr], normed=True, bins=np.linspace(-6,1, num=21), alpha=0.5)
ax2.hist(x2[:curr], normed=True, bins=np.linspace(0,15,num=21), alpha=0.5)
ax3.hist(x3[:curr], normed=True, bins=np.linspace(7,20,num=21), alpha=0.5)
ax4.hist(x4[:curr], normed=True, bins=np.linspace(14,20,num=21), alpha=0.5)
simulation = animation.FuncAnimation(fig, updateData, interval=50, repeat=False)
plt.show()
Upvotes: 7
Reputation: 2171
Got it!
My iterating over n was the culprit. This does what I expected:
def updateData(curr):
curr2=100+curr*5
#if curr == n:
# a.event_source.stop()
ax1.hist(x1[:curr2], normed=True, bins=20, alpha=0.5)
ax2.hist(x2[:curr2], normed=True, bins=20, alpha=0.5)
ax3.hist(x3[:curr2], normed=True, bins=20, alpha=0.5)
ax4.hist(x4[:curr2], normed=True, bins=20, alpha=0.5)
simulation = animation.FuncAnimation(fig, updateData, frames=900, interval=10)
plt.show()
Upvotes: -1