Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
614 views
ubuntu2004
Kernel: Python 3 (system-wide)

The Barnsley Fern

[ref: https://scipython.com/book/chapter-7-matplotlib/examples/the-barnsley-fern/]

The Barnsley Fern is a fractal which resembles the Black Spleenwort species of fern. It is constructed by plotting a sequence of points in the (x,y) plane, starting at (0,0), generated by the following affine transformations f1, f2, f3, and f4 where each transformation is applied to the previous point and chosen at random with probabilities p1=0.01p_1=0.01, p2=0.85p_2=0.85, p3=0.07p_3=0.07 and p4=0.07p_4=0.07.

f1(x,y)=(0000.16)(xy)f2(x,y)=(0.850.04−0.040.85)(xy)+(01.6)f3(x,y)=(0.2−0.260.230.22)(xy)+(01.6)f4(x,y)=(−0.150.280.260.24)(xy)+(00.44)\begin{align*} f_1(x,y) &= \left( \begin{array}{ll} 0 & 0\\0 & 0.16 \end{array}\right) \left( \begin{array}{l}x\\y\end{array} \right)\\ f_2(x,y) &= \left( \begin{array}{ll} 0.85 & 0.04\\-0.04 & 0.85 \end{array}\right) \left( \begin{array}{l}x\\y\end{array} \right) + \left( \begin{array}{l}0\\1.6\end{array} \right)\\ f_3(x,y) &= \left( \begin{array}{ll} 0.2 & -0.26\\0.23 & 0.22 \end{array}\right) \left( \begin{array}{l}x\\y\end{array} \right) + \left( \begin{array}{l}0\\1.6\end{array} \right)\\ f_4(x,y) &= \left( \begin{array}{ll} -0.15 & 0.28\\0.26 & 0.24 \end{array}\right) \left( \begin{array}{l}x\\y\end{array} \right) + \left( \begin{array}{l}0\\0.44\end{array} \right) \end{align*}

First we import necessary libraries for arrays and plotting:

import numpy as np import matplotlib.pyplot as plt import matplotlib.cm as cm

Next we set up the affine transformations:

f1 = lambda x,y: (0., 0.16*y) f2 = lambda x,y: (0.85*x + 0.04*y, -0.04*x + 0.85*y + 1.6) f3 = lambda x,y: (0.2*x - 0.26*y, 0.23*x + 0.22*y + 1.6) f4 = lambda x,y: (-0.15*x + 0.28*y, 0.26*x + 0.24*y + 0.44) fs = [f1, f2, f3, f4]

Then we set the number of points and width and height:

npts = 500 # Canvas size (pixels) width, height = 300, 300 aimg = np.zeros((width, height))

Then we use a for loop to repeatedly apply the affine transormations:

x, y = 0, 0 for i in range(npts): # Pick a random transformation and apply it f = np.random.choice(fs, p=[0.01, 0.85, 0.07, 0.07]) x, y = f(x,y) # Map (x,y) to pixel coordinates. # NB we "know" that -2.2 < x < 2.7 and 0 <= y < 10 ix, iy = int(width / 2 + x * width / 10), int(y * height / 12) # Set this point of the array to 1 to mark a point in the fern aimg[iy, ix] = 1

Finally, plot the resulting image:

plt.imshow(aimg[::-1,:], cmap=cm.Greens) plt.show()
Image in a Jupyter notebook
ix
153
plt.imshow(aimg[::-1,:], cmap=cm.Reds) plt.show()
Image in a Jupyter notebook

Thank you for generating the Barnsley Fern!

#test

#Thank you for generating the Barnsley Fern!

hello