Fractal variations using Python

Every once in a while, I spend an hour or two playing with code to generate fractal images. I find these patterns intriguing and the process of working with them can make for a great workout in complex number arithmetic. When I’m playing with code like this, I find it particularly handy to use Python because it handles the complex numbers very neatly and you can produce a good looking fractal with just a few lines of code. For example, here’s a quick Mandelbrot example:

import numpy

print 'P2\n800 800\n255'

for y in numpy.linspace(-2.0,2.0,800):
    for x in numpy.linspace(-2.0,2.0,800):
        c = x + y*(0+1j)
        z = 0
        for p in range(256):
            z = z*z - c
            if numpy.abs(z) > 4:
                break
        print p,
    print

Please excuse the lack of explanatory comments, but I’m trying to make the point that you don’t need many lines of code!

I ran the program and piped the output into a plain text pgm file, then converted it to PNG format using ImageMagick’s convert command, as shown below:

python mandelbrot.py > mandelbrot.pgm
convert mandelbrot.pgm mandelbrot.png

Ok, here’s the image it produced:

mandelbrot

The process of generating each pixel value in an image like the one above involves starting with a complex number determined by the position within the image (the image spans a rectangular region of the complex plane) and iterating a function recursively to generate a sequence of other points on the complex plane. The faster this iterative process “blows up” (by which I mean that the complex numbers get very large) the darker the pixel.

Today, I was playing with this example and I decided to try to visualise something a little different – for each pixel, I repeated the iteration until the magnitude of the complex value passed a threshold (4 as it happens) then chose the pixel colour based on two things: the distance between the last two complex values and the difference in angle between them. I was thinking of this as “how fast the point is moving” and “how fast the point is revolving around the origin”. Neither of these descriptions are really completely appropriate for an iterative process like this which by definition moves in discrete steps, but that’s how I was thinking of it.

Anyway, the image I produced gave me much food for thought, so I figured I’d post it here in case I want to come back to it again. First, here’s the Python code:

import numpy

print 'P3\n1280 1280\n255'

for y in numpy.linspace(0.0,0.25,1280):
    for x in numpy.linspace(-2.5,-1.25,1280):
        c = x + y*(0+1j)
        z = 0
        for p in range(256):
            newz = z*z + c
            if numpy.abs(newz) > 4:
                z = newz - z
                break
            else:
                z = newz
        r = min(255, int(10 * numpy.abs(z)))
        g = min(255, 128 + int(10 * numpy.angle(z)))
        b = min(255, 128 - int(10 * numpy.angle(z)))
        print r, g, b,
    print

I ran the program and piped the output into a plain text ppm file, then converted it to PNG format using ImageMagick’s convert command, as shown below:

python colours.py > colours.ppm
convert colours.ppm colours.png

This image shows the region of the complex plane where the real part is between -3 and +3 and the imaginary part is between -3j and +3j.

colours1

This image shows the region of the complex plane where the real part is between -1.5 and -1.25 and the imaginary part is between 0j and 0.25j.

colours3

Advertisement
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s