SoFunction
Updated on 2024-11-17

Python Programming matplotlib Interactive Plotting Julia Set Example Explanation

The so-called Julia set is a wonderful pattern similar to the one below

在这里插入图片描述

Julia Collection

在这里插入图片描述

In particular, when c = an initial value of z, the set of z's that satisfy the convergence condition constitute the famous Mandelbrot set

Mandelbrot集

In the above figure, the color indicates the rate of divergence of the point, which can be interpreted as the number of iterations at the beginning of the divergence. The code for its generation is also very simple:

#
import numpy as np
import time
import  as plt
# Generate z-coordinate, axis is the starting position, nx, ny is the number of grid points in x- and y-directions
def genZ(axis,nx,ny):
    x0,x1,y0,y1 = axis
    x = (x0,x1,nx)
    y = (y0,y1,ny)
    real, img = (x,y)
    z = real + img*1j
    return z
# Get Julia set, n is the number of iterations, m is the judgment dispersion point, greater than 1 can be
def getJulia(z,c,n,m=2):
    t = ()
    c = np.zeros_like(z)+c
    out = abs(z)
    for i in range(n):
        absz = abs(z)
        z[absz>m]=0		# Set zero to the point where the divergence begins
        c[absz>m]=0		
        out[absz>m]=i	# Record the rate of dispersion of the dispersion point
        z = z*z + c
    print("time:",()-t)
    return out
if __name__ == "__main__":
    axis = ([-2,1,-1.5,1.5])
    z0 = genZ(axis,500,500)
    mBrot = getJulia(z0,z0,50)
    (mBrot, cmap=, extent=axis)
    ().set_axis_off()
    ()

matplotlib binding events

In the following, we would like to realize that clicking on a point in the Mandelbrot set generates the corresponding Julia set.
In mpl, the event binding function mpl_connect is encapsulated in theCavnas classin which the call is formatted as

canvas.mpl_connect('str', func)

where func event function, the string is passed into the event function of the event identification, as listed below, look at the meaning of the word can be

'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'

For simplicity, we can start by detecting the mouse click event 'button_press_event', for which we need to define an event function with a slight modification of the entry function above:

def test(evt):
    print()	#xdata i.e. x-direction coordinates
if __name__ == "__main__":
    axis = ([-2,1,-1.5,1.5])
    z0 = genZ(axis,500,500)
    mBrot = getJulia(z0,z0,50)
    fig, ax = ()
    .mpl_connect('button_press_event', test)# Call event functions
    (mBrot, cmap=, extent=axis)
    ().set_axis_off()
    ()	

So clicking on the image that comes out of imshow() returns the corresponding x-coordinate.

python 
time: 0.47572827339172363
-0.8652597402597402
-0.7840909090909087
-0.18344155844155807
0.23051948051948123
0.8149350649350655

resizing

Then generating the Julia set only requires a single re-call togetJuliaThis function is sufficient.
The fractal character of the Mandelbrot set means that the images we generate can be zoomed in infinitely, but the zoom tool that comes with mpl doesn't regenerate the data, so it's a spurious zoom. So we need to rebind the zoom operation, the idea is to record the coordinates at this point when the right button is clicked ('button_press_event'), and redraw the picture when the right button is released ('button_release_event') is put, in order to prevent conflict with the left button, so in the In order to prevent conflict with the left button, we add the left and right button judgment in the event function corresponding to the click.

The result is shown in Figure

在这里插入图片描述

In addition, the mouse wheel can be bound to achieve true scaling of the Mandelbrot set at that point, with the following code

import  as plt
import numpy as np
from matplotlib import cm
import matplotlib.backend_bases as mbb
import time
class MandelBrot():
    def __init__(self,x0,x1,y0,y1,n):
         = ([x0,x1,y0,y1])        	# Initial coordinates
         = 
        ,, = n,n,n               # of grid divisions in the x,y direction
         = 100                                # of iterations
        self.n0 = 0                                     # of pre-iterations
         = genZ(,,)
        ()
    def DrawMandelbrot(self):
        mBrot = getJulia(,,)       
        , ax = ()
        (mBrot, cmap=, extent=)
        ().set_axis_off()        
        .mpl_disconnect(.key_press_handler_id)
        .mpl_connect('button_press_event', )
        .mpl_connect('button_release_event', )
        .mpl_connect('scroll_event', )       
        ()
    def DrawJulia(self,c0):
        z = genZ([-2,2,-2,2],800,800)
        julia = getJulia(z,c0,)        
        jFig,jAx = ()
        ()
        (julia, cmap=, extent=)
        ().set_axis_off()
        ()
        .draw_idle()	
	# Scroll wheel zoom
    def OnScroll(self,evt):
        x0,y0 = ,
        if  == "up":
             = (+[x0,x0,y0,y0])/2
        elif  == 'down':
             = 2*-[x0,x0,y0,y0]
        z = genZ(,,)
        mBrot = getJulia(z,z,)
        ()
        (mBrot, cmap=, extent=)
        ().set_axis_off()        
        mBrot[mBrot<1]==self.n0+
        self.n0 = int((mBrot))
        .draw_idle()
        pass
    def OnMouse(self, evt):
         = 
         = 
        .draw_idle()    
    def OnRelease(self,evt):
        x0,y0,x1,y1 = ,,,
        if  == :
            (x1+y1*1j)		# If the release was a left click, then draw the Julia set and return the
            return
        #Right-click and drag to zoom in realistically on the Mandelbrot set
         = ([min(x0,x1),max(x0,x1),
                             min(y0,y1),max(y0,y1)])        
        nxny = [[1,3]]-[[0,2]]
        , = (nxny/max(nxny)*).astype(int)
        z = genZ(,,)
        n = 100     #n is the number of iterations
        mBrot = getJulia(z,z,n)
        ()
        (mBrot, cmap=, extent=)
        ().set_axis_off()        
        mBrot[mBrot<1]==self.n0+n
        self.n0 = int((mBrot))
        .draw_idle()
def genZ(axis,nx,ny):
    x0,x1,y0,y1 = axis
    x = (x0,x1,nx)
    y = (y0,y1,ny)
    real, img = (x,y)
    z = real + img*1j
    return z
def getJulia(z,c,n,n0=0,m=2):
    t = ()
    c = np.zeros_like(z)+c
    out = abs(z)
    for _ in range(n0):
        z = z*z + c
    for i in range(n0,n0+n):
        absz = abs(z)
        z[absz>m]=0
        c[absz>m]=0
        out[absz>m]=i
        z = z*z + c
    print("time:",()-t)
    return out
if __name__ == "__main__":
    x,y = 0,0
    brot = MandelBrot(-2,1,-1.5,1.5,1000)

The above is python programming matplotlib interactive plotting Julia set sample analysis of the details, more information about matplotlib interactive plotting Julia set please pay attention to my other related articles!