Search code examples
pythonpython-3.xcolorsmandelbrot

How to properly configure coloring for mandelbrot set using python?


Looking for trainings on python I decided to draw the mandelbrot set using a script. Drawing it wasn't too complicated so I decided to use color and I discovered the smooth coloring algorithm. Using this question I was able to render something really beautiful and similar to this one.

To achieve that I set up a gradation color palette using three "steps" : From dark blue to light blue, then light blue to yellow and finally yellow to dark brown. The overall image is perfect.

Problem comes when I try too zoom in. Let's take the example of this area. When I'm at this level of zoom, my script doesn't draw dark blue anymore. I think I mis coded something because whereever you see dark blue on the wikipedia image, I have dark brown (so a color near the end of my palette). When I first thought about this I told myself if the pattern is going back to the original one, then it should use the same colors cause escape time should be the same.

So, was this coloring configured in the palette or is there something about escape time I didn't understand ?

Here is the code I use for the coloring :

def color_pixel(n, z):
    smoothcolor = n + 1 - math.log(math.log(abs(z)))/math.log(2)
    f = smoothcolor/iterate_max
    i = int(f*500)
    color = palette[i]
    return color

500 is the number of colors in my palette (len(palette)-1).

z the value of z when it escaped over 10.

I use 100 as the max iterations but same results with a higher value.

Thanks !


Solution

  • My colouring method is to use a rotative array in three sections. First blue cross-fades to green without using red, then green to red without using blue, and finally red to (almost) blue with no green, where the next iteration level will wrap back to pure blue at the bottom of the array by using a modulus of the iterations.

    However when I made a supposedly smoothe realtime zoom (by storing the data with a doubling scale, and then in-betweening 16 frames by interpolation for playback), I found that in the neighbourhood of the M-set, where the contours look chaotic, the effect was messy as the colours tend to dance around. There I used a different scheme, bending the colours to a gray scale.

    My final colouring method was to use the rotating palette for pixels having one or more neighbours of the same depth, but tending towards mid-gray depending on how many neighbours were different. Bear in mind though, that the requirements for a moving image are different from a static image, and sharp detail is not necessarily desirable.

    At deep zooms the number of iterations needed to extract the detail can be 1000 or more. I solved the problem laterally. I do not brute-force the map calculations. I developed a curve-stitching method that follows the contour of an iteration level, and then fills the region. In the smoothly changing areas that means large areas do not have to be iterated. Similarly for the M-Set itself where the function has not escaped - I avoid iterating there as far as possible by again trying to follow round its edge and then filling. This method can suffer from nipping off some detail, but the speed gain is enormous. In the chaotic region near the edge of the M-Set my method was to just iterate at every pixel.