Plot Mandelbrot with matplotlib / pyplot / numpy / python
Asked Answered
S

4

9

I am new to python and learning by following Python "Scientific lecture notes Release 2013.1" tutorial. Please help me solve this Mandelbrot problem in the srcreenshot below (Pg 71). Please provide step-wise commands with explanation if possible because programming concepts are new to me.

http://dl.dropbox.com/u/50511173/mandelbrot.png

I tried to solve this as follows:

import numpy as np
import matplotlib.pyplot as plt

x,y=np.ogrid[-2:1:10j,-1.5:1.5:10j]
c=x + 1j*y
z=0
for g in range(50):
  z=z**2 + c

plt.imshow(z.T, extent=[-2,1,-1.5,1.5])

I encountered the following error "TypeError: Image data can not convert to float"

What does this error exactly mean and how to correct it? I am finding it difficult to understand the imshow() function. What do the individual terms inside imshow() mean?

Thank You.

Sices answered 22/2, 2013 at 12:40 Comment(0)
D
6

The Mandelbrot set is not the values of z you are trying to plot, which are giving you problems because they are complex numbers. The Mandelbrot set is made up of the points p of the complex plane for which the recurrence relation z_n = z_n-1**2 + p remains bounded. This is checked in a practical way by comparing the result after a few iterations to some threshold. In your case, if you add the following lines after your for loop:

threshold = 2
mask = np.abs(z) < threshold

and then plot mask you should see the set plot on screen.

To understand the general workings of imshow's arguments, you will be better off reading the docs than asking here.

Delanos answered 22/2, 2013 at 13:32 Comment(0)
S
6

Thanks to @Jan and @Jaime. I got it working as follows, takes too much time to calculate though:

import numpy as np
import scipy as sp
import matplotlib.pyplot as plt


x,y=np.ogrid[-2:1:5000j,-1.5:1.5:5000j]

print('')
print('Grid set')
print('')

c=x + 1j*y
z=0

for g in range(500):
        print('Iteration number: ',g)
        z=z**2 + c

threshold = 2
mask=np.abs(z) < threshold

print('')
print('Plotting using imshow()')
plt.imshow(mask.T,extent=[-2,1,-1.5,1.5])

print('')
print('plotting done')
print('')

plt.gray()

print('')
print('Preparing to render')
print('')

plt.show()

Image Result

Sices answered 23/2, 2013 at 7:8 Comment(0)
M
2

You get this error because plt.imshow does not accept arrays of complex numbers. You can address the real or imaginary part of an array Z as Z.real or Z.imag. Thus if you want to plot the real part

plt.imshow(z.real.T, extent=[-2,1,-1.5,1.5])

would do the job.

The arguments in 'imshow' define the following things.

If z is a N-by-M matrix, it is interpreted as point values on a regular grid. By extent you specify how this grid extends in space...

Machute answered 22/2, 2013 at 13:9 Comment(0)
P
2

You're trying to plot a complex value with imshow which is why you're getting that error, can use a threshold as others have suggested, but you might want to consider using np.angle or np.abs as well. You can also simplify your calculation of z using Python's built-in reduce method.

Had some fun with this one, but this shows the general idea:

import numpy as np
import matplotlib.pyplot as plt

%matplotlib inline

x, y = np.ogrid[-2:1:500j, -1.5:1.5:500j]

# Increase this to improve the shape of the fractal
iterations = 9

c = x + 1j*y

z = reduce(lambda x, y: x**2 + c, [1] * iterations, c)

plt.figure(figsize=(10, 10))
plt.imshow(np.angle(z));

plt.figure(figsize=(10, 10))
plt.imshow(np.log(np.abs(z)));
Payson answered 18/4, 2015 at 4:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.