How to render nice fractal images with numpy in one second
Rendering fractals like the Mandelbrot set, the Julia set and the Newton fractal are almost routine exercises for every beginner in python. They are very easy to code and can produce quite appealing images.
The only headache when rendering fractals with python is efficiency: python is notoriously slow for doing large scale numeric computations, even most people know they should use
numpy to accelarate this process, they did not explore the full power of
numpy and very few people know that their programs could be further accelarated by using
In this program I tried to do my best in the following respects:
- The code should be as simple as possible.
- The code should run as fast as possible.
- The result should be as nice as possible.
Of course one cannot expect he could render very artistic fractal images within only a few lines of code, but he can do quite good in all these three respects, this is what I want to show you in this post.
The main tips and tricks are:
numpy.ogridto create your 2D grid in the complex plane.
numpy.frompyfuncto vectorize your “escaping time” function.
numbato specify the data type of the inputs and the outputs. Just add an one-line decorator!
- Do not use the
putpixelfunction in PIL to iterate over the pixels,
fromarrayis a better choice.
- Explictly write
z.real*z.real+z.imag*z.imaginstead of using the
z*zis a bit faster than
z*z*zis a bit faster than
- Finally choose a nice coloring scheme for your image.
To summary, the most import thing you should keep in mind is that
Always use vectorized operations instead of the for loop to iterate over the 2D array and render the image. This is because in vectorized operations the CPU can read and send a bunk of data at a time instead of one.
A suitable, simple numba decorator could improve the efficiency a lot.