使用matplotlib/pyplot/numpy/python绘制曼德尔布罗特集合

9 投票
4 回答
16993 浏览
提问于 2025-04-17 16:45

我刚开始学习Python,正在跟着《Python科学讲义 2013.1版》的教程学习。请帮我解决下面截图中的Mandelbrot问题(第71页)。如果可以的话,请提供逐步的命令和解释,因为编程对我来说还是个新鲜事。

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

我尝试这样解决这个问题:

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])

但我遇到了一个错误:“TypeError: Image data can not convert to float”。

这个错误到底是什么意思?我该如何修正它?我发现理解imshow()这个函数有点困难。imshow()里面的每个参数是什么意思呢?

谢谢你。

4 个回答

2

你会遇到这个错误是因为 plt.imshow 不支持复数数组。你可以通过 Z.realZ.imag 来获取数组 Z 的实部或虚部。因此,如果你想绘制实部,

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

这样就可以了。

在 'imshow' 中的参数定义了以下内容。

如果 z 是一个 N 行 M 列的矩阵,它会被解释为在一个规则网格上的点值。通过 extent 你可以指定这个网格在空间中的扩展方式……

6

感谢@Jan和@Jaime的帮助。我已经让它工作了,下面是我的代码,不过计算起来花了不少时间:

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()

结果图

6

曼德尔布罗集合并不是你想要绘制的那些z值,这些值是复杂数,所以会让你遇到问题。曼德尔布罗集合是由复平面上的点p组成的,这些点满足一个递归关系z_n = z_n-1**2 + p,并且这个关系的结果是有界的。我们可以通过在几次迭代后将结果与某个阈值进行比较来检查这一点。在你的情况下,如果在for循环后添加以下几行代码:

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

然后绘制mask,你应该能在屏幕上看到集合的图像。

要理解imshow的参数是怎么工作的,建议你去看看文档,比在这里问更有帮助。

撰写回答