Last year we considered complex numbers, quantities with two degrees of freedom. These numbers have many important applications in engineering, but can we immediately use them to do something interesting?
Well, we can draw the Mandelbrot set with a computer and a bit of ingenuity. This set includes every complex number for which the following recurrence equation never produces a result with an absolute value (distance from the complex origin) greater than two:
For any complex number, we start with z = 0
, square it, add our complex candidate c
, then repeat the process with z
equal to the new (complex) value. As long as z
stays close to the origin after many iterations, our candidate is probably in the Mandelbrot set. Since complex numbers behave like points in a 2D plane, we can draw an image where each pixel is colored by testing a candidate c
related to its horizontal and vertical position.
So let’s make a drawing! This program is based on Prez Jordan’s Python code, but we’ll add a gradient to show how many iterations each candidate takes to escape. First we set up a 600×600 canvas with Tkinter:
from Tkinter import Tk, Canvas, mainloop
tk = Tk()
w = Canvas(tk, width=600, height=600)
Next we define our mandel()
function which takes a complex number and tests whether it escapes in twenty iterations. If so the function returns the last iteration number, otherwise it returns 99:
def mandel(c):
z = 0
i = 0
for h in range(0,20):
z = z*z + c
if abs(z) > 2:
break
else:
i+=1
if abs(z) >= 2:
return i
else:
return 99
In order to draw a gradient, let’s use a dictionary to map iterations to colors. We’ll need entries for keys 0-20 and 99:
colors = {
0: 'white',
1: 'white',
2: 'light yellow',
3: 'light yellow',
4: 'lemon chiffon',
5: 'lemon chiffon',
6: 'yellow',
7: 'yellow',
8: 'gold',
9: 'gold',
10: 'orange',
11: 'orange',
12: 'orange red',
13: 'orange red',
14: 'red',
15: 'red',
16: 'red',
17: 'dark red',
18: 'dark red',
19: 'dark red',
20: 'dark red',
99: 'black'
}
Finally we loop over each pixel, convert its x and y coordinates to a complex number, test that number by passing it to the mandel()
function, and use the returned key to look up the appropriate color in our dictionary:
print "Drawing..."
for x in range(0,600):
real = x / 200.0 - 2.2
for y in range(0, 600):
imag = y / 200.0 - 1.5
c = complex(real, imag)
p = mandel(c)
w.create_line(x, 600-y, x+1, 601-y, fill=colors[p])
w.pack()
print "Complete!"
mainloop()
Run this code in your Python interpreter and see a picture of the Mandelbrot set!
[…] Last time we plotted a Mandelbrot set using a small Python script. This set is interesting because an unexpectedly large amount of detail emerges from the iteration of a relatively simple function. Even more interesting is the fact that this detail is not limited to any particular resolution. The Mandelbrot set exhibits fractal geometry, meaning that tiny areas of the set share features with the whole thing. If we zoom in, smaller details are visible no matter how far we choose to zoom. […]