Julia Set Plotting Extension

Load module for a JuliaSet that conforms to the specified interface.

It is wise to run the test suite in test_juliaset.py with nosetests prior to attempting to plot here.


In [68]:
from juliaset import JuliaSet

Load additional libraries needed for plotting and profiling.


In [69]:
# 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.

Extend JuliaSet class with additional functionality.


In [70]:
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(4.0 / self._d)
    
    def render(self):
        """Render image as square array of ints"""
        if not self.set.any(): self.generate()
        #if not self.set: 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(self.img.size))
        #dim = self.img.size
        print(self.img.size)
        self.img = np.reshape(self.img, (dim,dim)).T
        
    def show(self):
        """Use matplotlib to plot image as an efficient mesh"""
        if not self.img.size: self.render()
        plt.figure(1, figsize=(12,9))
        '''fig = plt.figure()
        #ax = fig.add_subplot(1, 1, 1)
        #data = np.random.random((N,7))
        x = data[:,0]
        y = data[:,1]
        points = data[:,2:4]'''
        
        xy = np.linspace(-2,2,int(sqrt(self.img.size)))
        #xy = np.linspace(-2,2,self.get_dim())
        plt.pcolormesh(xy, xy, self.img, cmap=plt.cm.hot)
        plt.colorbar()
        #ax.scatter(x, y, color = rgb)
        plt.show()
        
    def interact(self):
        """Use bokeh to plot an interactive image"""
        from matplotlib.colors import rgb2hex
        if not self.img.size: self.render()
        # 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=(-2,2), y_range=(-2,2), plot_width=600, plot_height=600)
        f.image(image=[self.img], x=[-2], y=[-2], dw=[4], dh=[4], palette=bokehpalette, dilate=True)
        blt.show(f)

Visualize a Julia set using matplotlib.


In [71]:
#j = JuliaSetPlot(0 + 0j)
#j = JuliaSetPlot(-1 + 0j)
#j = JuliaSetPlot(0.3 + 0j)
#j = JuliaSetPlot(-.8 + .2j)
j = JuliaSetPlot(-.835 + .2321j)
#j = JuliaSetPlot(-1.037 + 0.17j)
%time j.set_spacing(0.005)
%time j.generate()
%time j.show()


CPU times: user 8 ms, sys: 4 ms, total: 12 ms
Wall time: 37.4 ms
CPU times: user 1.48 s, sys: 8 ms, total: 1.49 s
Wall time: 1.5 s
640000
CPU times: user 1.32 s, sys: 356 ms, total: 1.67 s
Wall time: 3.2 s

Visualize a different Julia set using Bokeh as an interactive Javascript plot.


In [72]:
#j = JuliaSetPlot(0 + 0j)
#j = JuliaSetPlot(-1 + 0j)
#j = JuliaSetPlot(0.3 + 0j)
#j = JuliaSetPlot(-.8 + .2j)
j = JuliaSetPlot(-.835 + .2321j)
#j = JuliaSetPlot(-1.037 + 0.17j)
#j = JuliaSetPlot(-0.624 + 0.435j)
%time j.set_spacing(0.005)
%time j.generate()
%time j.interact()


CPU times: user 12 ms, sys: 4 ms, total: 16 ms
Wall time: 49.7 ms
CPU times: user 1.5 s, sys: 16 ms, total: 1.52 s
Wall time: 1.53 s
640000
CPU times: user 232 ms, sys: 48 ms, total: 280 ms
Wall time: 476 ms

In [73]:
%prun j.generate()


 

In [74]:
%load_ext line_profiler
%lprun -f j.generate j.generate()

In [ ]: