This example is based on a blog post from John D. Cook.
I couldn't resist writing a version in a more NumPy-ish style.
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
def midpoint(*args):
return np.mean(args, axis=0)
# Three corners of an equilateral triangle
corner = np.array([(0, 0), (0.5, np.sqrt(3)/2), (1, 0)])
corner[1]
array([0.5 , 0.8660254])
N = 1000
p = np.zeros((N, 2))
p[0] = midpoint(corner[0], corner[1])
p[0]
array([0.25 , 0.4330127])
ks = np.random.choice(3, 1000)
for i, k in enumerate(ks):
p[i] = midpoint(p[i-1], corner[k])
xs, ys = np.transpose(p)
plt.scatter(xs, ys, s=1)
plt.axis([-0.1, 1.1, -0.1, 0.95])
plt.xticks([])
plt.yticks([])
plt.show()
points_per_step = 10
steps = len(p) // points_per_step
%%capture
fig, ax = plt.subplots()
ax.axis([-0.1, 1.1, -0.1, 1.1])
plt.xticks([])
plt.yticks([])
scatter = ax.scatter([],[], s=2)
def animate(i):
scatter.set_offsets(p[:i*points_per_step])
from matplotlib.animation import FuncAnimation
anim = FuncAnimation(fig, animate, frames=steps)
from IPython.display import HTML
HTML(anim.to_jshtml())