In [2]:
# Math libraries
import numpy as np
from math import sqrt

# Matplotlib plotting libraries
import matplotlib.pyplot as plt
%matplotlib inline

# Bokeh plotting libraries
import bokeh.plotting as blt
blt.output_notebook()


BokehJS successfully loaded.

In [3]:
class JuliaSet(object):
    
    def __init__(self,c,n=100):
        self.c = c
        self.n = n
        self._d = 0.001
        self._complexplane = np.array([])
        self.set = np.array([])

      
    def juliamap(self,z):
        return z**2 + self.c
    
    def iterate(self,z):
        m=0
        while True:
            z=self.juliamap(z)
            m+=1
            if abs(z)>2:
                return m
            if m>=self.n:
                return 0
            
            
    
    def set_spacing(self,d,k=-2,s=2):
        self._d=d
        self.k=k
        self.s=s
        r=np.arange(k,s,self._d)
        x , y = np.meshgrid(r,r)
        self._complexplane = x+y*1j
        
    def generate(self):
        iterate = np.vectorize(self.iterate)
        self.set= iterate(self._complexplane)
        return self.set

In [4]:
class JuliaSetPlot(JuliaSet):
    """Extend JuliaSet to add plotting functionality"""
    
    def __init__(self, *args, **kwargs):
        # Invoke constructor for JuliaSet first, unaltered
        JuliaSet.__init__(self, *args, **kwargs)
        # Add another attribute: a rendered image array
        #self.img = np.array([])
    
    def get_dim(self):
        """Return linear number of points in axis"""
        return int(sqrt(self.set.size))
    
    #def render(self):
    #    """Render image as square array of ints"""
    #    if not self.set.size: self.generate()
    #    # Convert inefficient list to efficient numpy array
    #    self.img = np.array(self.set)
    #    # Reshape array into a 2d complex plane
    #    dim = int(sqrt(len(self.img)))
    #    self.img = np.reshape(self.img, (dim,dim)).T
        
    def show(self):
        """Use matplotlib to plot image as an efficient mesh"""
        if not self.set.size: self.generate()
        plt.figure(1, figsize=(12,9))
        xy = np.linspace(self.k,self.s,self.get_dim())
        plt.pcolormesh(xy, xy, self.set, cmap=plt.cm.hot)
        plt.colorbar()
        plt.show()
        
    def interact(self):
        """Use bokeh to plot an interactive image"""
        from matplotlib.colors import rgb2hex
        if not self.set.size: self.generate()
        # Mimic matplotlib "hot" color palette
        colormap = plt.cm.get_cmap("hot")
        bokehpalette = [rgb2hex(m) for m in colormap(np.arange(colormap.N))]
        # Create bokeh figure
        f = blt.figure(x_range=(self.k,self.s), y_range=(self.k,self.s), plot_width=600, plot_height=600)
        f.image(image=[self.set], x=[self.k], y=[self.k], dw=[self.s-self.k], dh=[self.s-self.k], palette=bokehpalette, dilate=True)
        blt.show(f)

In [5]:
j = JuliaSetPlot(1j)
%time j.set_spacing(0.006)
%time j.generate()
%time j.show()


CPU times: user 12 ms, sys: 0 ns, total: 12 ms
Wall time: 10.8 ms
CPU times: user 592 ms, sys: 8 ms, total: 600 ms
Wall time: 606 ms
CPU times: user 932 ms, sys: 288 ms, total: 1.22 s
Wall time: 1.21 s

In [6]:
j = JuliaSetPlot(2+1j)
%time j.set_spacing(0.006)
%time j.generate()
%time j.show()


CPU times: user 4 ms, sys: 4 ms, total: 8 ms
Wall time: 9.09 ms
CPU times: user 508 ms, sys: 8 ms, total: 516 ms
Wall time: 518 ms
CPU times: user 1 s, sys: 332 ms, total: 1.33 s
Wall time: 1.57 s

In [7]:
j = JuliaSetPlot(-1+2j)
%time j.set_spacing(0.006)
%time j.generate()
%time j.show()


CPU times: user 12 ms, sys: 0 ns, total: 12 ms
Wall time: 13.3 ms
CPU times: user 468 ms, sys: 16 ms, total: 484 ms
Wall time: 481 ms
CPU times: user 1.02 s, sys: 352 ms, total: 1.37 s
Wall time: 1.38 s

In [8]:
j = JuliaSetPlot(-1j)
%time j.set_spacing(0.006)
%time j.generate()
%time j.show()


CPU times: user 8 ms, sys: 4 ms, total: 12 ms
Wall time: 13.1 ms
CPU times: user 652 ms, sys: 8 ms, total: 660 ms
Wall time: 675 ms
CPU times: user 1.3 s, sys: 148 ms, total: 1.45 s
Wall time: 1.93 s

In [9]:
j = JuliaSetPlot(1)
%time j.set_spacing(0.006)
%time j.generate()
%time j.show()


CPU times: user 8 ms, sys: 0 ns, total: 8 ms
Wall time: 8.22 ms
CPU times: user 476 ms, sys: 12 ms, total: 488 ms
Wall time: 489 ms
CPU times: user 936 ms, sys: 320 ms, total: 1.26 s
Wall time: 1.2 s

In [ ]:
j = JuliaSetPlot(-1)
%time j.set_spacing(0.006)
%time j.generate()
%time j.show()


CPU times: user 8 ms, sys: 0 ns, total: 8 ms
Wall time: 8.69 ms
CPU times: user 2.63 s, sys: 16 ms, total: 2.64 s