python交互绘制茱莉亚集

  

matplotlib的展示面板中提供了放大,移动等交互式操作,但也未能涵盖所有的交互需求,比如希望通过mandelbrot集上的一点来生成对应的茱莉亚集。

Julia集

茱莉亚可以说是分形鼻祖,指的是对于给定的一个复数ccc,使得迭代式f (z) z=z2 + cf (z)=^ 2 + cf (z)=z2 + c收敛的复数打鼾声的集合。例如,当c=0=0 c=0时,那么其收敛区间为z2<1 z ^ 2 & lt; 1 z2<1的单位圆,对应的ccc的Julia集便是cos ?θ+型号?θ\ cosθ+ i \ \罪\ thetacosθ+ isinθ。

特别地,当c=佐=佐=z的初始值时,符合收敛条件的打鼾声的便构成大名鼎鼎的Mandelbrot集

它的图的颜色表示该点的发散速度,可以理解为开始发散时迭代的次数。其生成代码也非常简单:

# mbrot。py

进口numpy np进口时间

进口pyplotlib。pyplot作为plt

#生成z坐标,轴为起始位置,nx,纽约为x向和y向的格点个数

def贞(轴、nx ny):

x0, x1, y0,日元=轴

x=np.linspace (x0, x1, nx)

y=np.linspace (y0, y1,纽约)

真实,img=np.meshgrid (x, y)

z=真实+ img * 1 j

返回z

#获取Julia集n为迭代次数,m为判定发散点,大于1即可

def getJulia (z, c, n, m=2):

t=time.time ()

c=np.zeros_like (z) + c

出=abs (z)

我的范围(n):

absz=abs (z)

z [absz> m]=0 #对开始发散的点置零

c [absz> m]=0

出[absz> m]=我#记录发散点的发散速度

z=* z + c

打印(“时间:time.time () - t)

返回了

if __name__==癬_main__”:

轴=np.array ([2 1, -1.5, 1.5])

z0=贞(轴,500500)

mBrot=getJulia (z0 z0 50)

plt。imshow (mBrot提出=厘米。飞机,程度=轴)

plt.gca () .set_axis_off ()

plt.show ()

matplotlib绑定事件

下面希望实现点击Mandelbrot集中的一点,生成相应的茱莉亚集。

在mpl中,事件绑定函数mpl_connect被封装在cavnas类中,调用格式为canvas.mpl_connect (str,   函数),其中func事件函数,字符串为被传入事件函数的事件标识,如下所列,望文生义即可

“button_press_event”

“button_release_event”

“draw_event”

“key_press_event”

“key_release_event”

“motion_notify_event”

“pick_event”

“resize_event”

“scroll_event”

“figure_enter_event”

“figure_leave_event”

“axes_enter_event”

“axes_leave_event”

“close_event”

简单起见,可以先检测一下鼠标点击事件button_press_event,对此我们需要定义一个事件函数,并将上面的入口函数稍加修改:

def测试(evt):

打印(evt.xdata) # xdata即x方向的坐标

if __name__==癬_main__”:

轴=np.array ([2 1, -1.5, 1.5])

z0=贞(轴,500500)

mBrot=getJulia (z0 z0 50)

无花果,ax=plt.subplots ()

fig.canvas。mpl_connect (button_press_event,测试)#调用事件函数

plt。imshow (mBrot提出=厘米。飞机,程度=轴)

plt.gca () .set_axis_off ()

plt.show ()

于是点击imshow()出来的图片,即可返回相应的x坐标。

python mbrot。py

时间:0.47572827339172363 -0.8652597402597402

-0.7840909090909087

0.23051948051948123 -0.18344155844155807 0.8149350649350655

缩放

那么生成Julia集只需要重新调用一次getJulia这个函数即可。

Mandelbrot集的分形特征意味着我们所生成的图片可以无限放大,但是mpl自带的放大工具并不会重新生成数据,所以是虚假的放大。因此需要重新绑定放大操作,其思路是,当右键点击(“button_press_event”)时,记录此时的坐标,当右键释(button_release_event)放时重新绘制图片,为了防止与左键冲突,所以在点击所对应的事件函数中加入左右键判断。其结果如图

此外,还可以绑定鼠标滚轮,实现Mandelbrot集在该点的真实缩放,代码如下

进口matplotlib。pyplot作为plt

进口numpy np

从matplotlib进口厘米

进口matplotlib。backend_bases作为黑带大师

类导入时间曼德布洛特():

def __init__(自我,x0, x1, y0, y1, n):

自我。oriAxis=np.array ([x0, x1, y0, y1]) #初始坐标

自我。轴=自我。oriAxis

self.nx, self.ny,自我。nMax=n, n, n # x, y方向的网格划分个数

自我。硝石=100 #迭代次数

自我。n0=0 #预迭代次数

自我。z=贞(self.oriAxis self.nx self.ny)

self.DrawMandelbrot ()

def DrawMandelbrot(自我):

mBrot=getJulia (self.z、self.z self.nIter)

自我。无花果,ax=plt.subplots ()

plt。imshow (mBrot提出=厘米。飞机,程度=self.axis)

python交互绘制茱莉亚集