# Sierpiński Triangle: Fractal Christmas Tree

The Sierpiński triangle named after the Polish mathematician Wacław Sierpiński), is a fractal with a shape of an equilateral triangle. The triangle is subdivided indefinitely into smaller equilateral triangles resembling exactly the original triangle. As such, the Sierpiński triangle really resembles a Christmas tree. An infinite Christmas tree! With this fractal, you will never run out of Christmas trees 😁

The Sierpiński Triangle as a Christmass Tree

In this short post, we will see how to create such a fractal in Python. Then, we will create an animated visualization using the Matplotlib Animation API.

## How to create the triangle?

There are multiple ways to generate the triangle as summarized in the Wikipedia article for the Sierpiński triangle. One of the most popular methods is the one based on Chaos Game. Here is how it works in short.

First, we need to take any three points in the plane that form an equilateral triangle. Without loss of generality, we can select the points $$A = (0.0, 0.0), B = (0.5, 1.0), C = (1.0, 0.0)$$. We don't need to draw these points. Then we randomly select any point inside the triangle, considering it as the current position $$P$$. Then, we repeat the following 3 steps over and over:

1. Randomly select any of the three vertex points $$A, B, C$$. Let's denote it as $$R$$
2. Move half the distance from the current position $$P$$ to the selected vertex $$R$$
3. Plot the current position

Here is an implementation in Python:

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import random from operator import add def generate_sierpinski_triangle(n: int): sierpinski_triangle = [] # final list of points # initial points A = (0.0, 0.0) B = (0.5, 1.0) C = (1.0, 0.0) triangle_vertices = [A, B, C] # starting point moving_point = random.choice(triangle_vertices) for i in range(n): offset_point = random.choice(triangle_vertices) moving_point = list(map(lambda x: x / 2.0, list(map(add, moving_point, offset_point)))) sierpinski_triangle.append(moving_point.copy()) return sierpinski_triangle 

Next, we'll see how to make an animation.

## Making an animation: triangle within a triangle

To demonstrate the fractal nature of the triangle we will make an animation by zooming in on one part of the original triangle. For this purpose, we use the Matplotlib Animation API.

It is quite straightforward to make such an animation. In each iteration, we draw all the points, but we only reduce the x- and y-axis limits as a function of the iteration number. This creates a zooming effect. The Python implementation is given below:

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import matplotlib.pyplot as plt import matplotlib.animation as animation def make_animation(sierpinski_triangle: list): num_points = len(sierpinski_triangle) points_split = list(zip(*sierpinski_triangle)) xx, yy = points_split, points_split fig = plt.figure(figsize=(10, 10)) def init(): ax = plt.axes(xlim=(0, 1), ylim=(0, 1)) ax.set_xticks([], []) ax.set_yticks([], []) ax.set_axis_off() return ax.plot(xx, yy, "g.") def animate(i): scale = 1 - i * 0.02 # calculate the new scale ax = plt.axes(xlim=(0, scale), ylim=(0, scale)) ax.set_xticks([], []) ax.set_yticks([], []) ax.set_axis_off() return ax.plot(xx, yy, "g.") anim = animation.FuncAnimation(fig, animate, init_func=init, frames=50, interval=200, blit=False) 

The resulting animation is shown below. As we can see the same structure appears again and again. Because this is a simulation, the number of points is finite, so the pattern will stop appearing at some point. If we were able to generate an infinite number of points, the pattern would never disappear.

Animation: Sierpiński Triangle Fractal