Histogram¶
This example uses the morph() animation with sequential=True to animate bins appearing gradually, and then reveal an approximate gaussian curve of the distribution. And it uses the XKCD style because why not.
import diplotocus as dpl
import numpy as np
import matplotlib.pyplot as plt
N = 5#Number of dice
l = 10#Number of faces per die
m = 10_000#Number of throws for each die
plt.xkcd()
tl = dpl.Timeline(xlim=(0,50),ylim=(0,0.075),bbox_inches='tight')
tl.ax.set_xlabel(f'Sum of {N}, {l}-faced dice averaged over {m} throws')
tl.ax.set_ylabel('Probability density')
#We generate dice throws and add up their result to get our distribution
throws = np.random.randint(1,l,size=(m,N))
sum = np.sum(throws,axis=1)
#We use numpy's histogram() function and plot the result with dpl.bar(), as it lets us animate
#the height of bars independently.
hist,edges = np.histogram(sum,bins=l*N,range=(1,N*l),density=True)
x = (edges[1:]+edges[:-1])/2
h = dpl.bar(x=x,height=0,width=(edges[1]-edges[0])/2)
h.morph(new_x=x,new_height=hist,duration=60,sequential=True,easing=dpl.easeInOutCubic())
#We then compute and plot a gaussian curve approximating our distribution.
x = np.linspace(0,50,50)
mu = N*l/2
sigma = np.sqrt(N*(l-1)**2/12)
y = 1/(sigma*np.sqrt(2*np.pi))*np.exp(-(x-mu)**2/(2*sigma**2))
p = dpl.plot(x,y,c='C1')
p.draw(duration=60,delay=60)
tl.animate((h,p))
tl.save_video('../../_static/examples/hist.mp4')
For those curious, here’s the math for the gaussian curve approximation:
We throw \(N\) dice that each have \(l\) labeled from 1 to \(l\).
For one die, the expected distribution is:
For \(N\) dice, we convolve each distribution \(p\):
By the Central Limit Theorem, we have \(\lim_{N\rightarrow\infty}P_N = \mathcal{N}(\mu,\sigma)\)
Trivially, the mean of this distribution is \(\mu = \frac{N\cdot l}{2}\).
For \(\sigma\), we know that the standard deviation of \(\mathcal{U(1,l)}\) is \(\sigma(\mathcal{U}(1,l))=\sqrt{\frac{(l-1)^2}{12}}\).
For \(N\) dice, we add the individual standard deviations quadratically, so we find \(\sigma^2\) = \(\Sigma_{i=0}^{N}\sigma(\mathcal{U}(1,l))^2 = N\sigma(\mathcal{U}(1,l))^2\), thus:
Here, we have \(N\)=5, big enough that our distribution can be well approximated by the following gaussian:
Try lowering the number of dice \(N\), you will notice our approximation hits its limits!