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 [1]:
from juliaset import JuliaSet

Load additional libraries needed for plotting and profiling.


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.

Extend JuliaSet class with additional functionality.


In [11]:
class JuliaSetPlot(JuliaSet):
    """Extend JuliaSet to add plotting functionality"""
    
    def __init__(self, *args, **kwargs):
        # Invoke constructor for JuliaSet first, unaltered
        super(JuliaSetPlot, self).__init__(*args, **kwargs)
        # Add one more attribute: a rendered image array
        self.img = np.array([])
    
    def get_dim(self):
        # get what should be an attribute
        return int(4.0 / self._d)
    
    def render(self):
        if not self.set: self.generate()
        # Convert inefficient list to efficient numpy array
        self.img = np.array(self.set)
        dim = self.get_dim()
        # Reshape array into a 2d complex plane
        self.img = np.reshape(self.img, (dim,dim)).T
        
    def show(self):
        if not self.img.size: self.render()
        # Specify complex plane axes efficiently
        xy = np.linspace(-2,2,self.get_dim())
        # Use matplotlib to plot image as an efficient mesh
        plt.figure(1, figsize=(12,9))
        plt.pcolormesh(xy,xy,self.img, cmap=plt.cm.hot)
        plt.colorbar()
        plt.show()
        
    def interact(self):
        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))]
        # Use bokeh to plot an interactive image
        f = blt.figure(x_range=[-2,2], y_range=[-2,2], plot_width=600, plot_height=600)
        f.image(image=[j.img], x=[-2,2], y=[-2,2], dw=[4], dh=[4], palette=bokehpalette)
        blt.show(f)

Visualize a Julia set using matplotlib.


In [12]:
j = JuliaSetPlot(-1.037 + 0.17j)
%time j.set_spacing(0.006)
%time j.show()


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-2a95bb0acec6> in <module>()
----> 1 j = JuliaSetPlot(-1.037 + 0.17j)
      2 get_ipython().magic(u'time j.set_spacing(0.006)')
      3 get_ipython().magic(u'time j.show()')

<ipython-input-11-2c3d5a46376a> in __init__(self, *args, **kwargs)
      4     def __init__(self, *args, **kwargs):
      5         # Invoke constructor for JuliaSet first, unaltered
----> 6         super(JuliaSetPlot, self).__init__(*args, **kwargs)
      7         # Add one more attribute: a rendered image array
      8         self.img = np.array([])

TypeError: must be type, not classobj

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


In [8]:
j = JuliaSetPlot(-0.624 + 0.435j)
%time j.set_spacing(0.006)
%time j.interact()


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-8-07d62513b9e7> in <module>()
----> 1 j = JuliaSetPlot(-0.624 + 0.435j)
      2 get_ipython().magic(u'time j.set_spacing(0.006)')
      3 get_ipython().magic(u'time j.interact()')

<ipython-input-3-2c3d5a46376a> in __init__(self, *args, **kwargs)
      4     def __init__(self, *args, **kwargs):
      5         # Invoke constructor for JuliaSet first, unaltered
----> 6         super(JuliaSetPlot, self).__init__(*args, **kwargs)
      7         # Add one more attribute: a rendered image array
      8         self.img = np.array([])

TypeError: must be type, not classobj

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


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-9-99630a369df8> in <module>()
----> 1 get_ipython().magic(u'prun j.generate()')

/projects/sage/sage-6.9/local/lib/python2.7/site-packages/IPython/core/interactiveshell.pyc in magic(self, arg_s)
   2334         magic_name, _, magic_arg_s = arg_s.partition(' ')
   2335         magic_name = magic_name.lstrip(prefilter.ESC_MAGIC)
-> 2336         return self.run_line_magic(magic_name, magic_arg_s)
   2337 
   2338     #-------------------------------------------------------------------------

/projects/sage/sage-6.9/local/lib/python2.7/site-packages/IPython/core/interactiveshell.pyc in run_line_magic(self, magic_name, line)
   2255                 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
   2256             with self.builtin_trap:
-> 2257                 result = fn(*args,**kwargs)
   2258             return result
   2259 

/projects/sage/sage-6.9/local/lib/python2.7/site-packages/IPython/core/magics/execution.pyc in prun(self, parameter_s, cell)

/projects/sage/sage-6.9/local/lib/python2.7/site-packages/IPython/core/magic.pyc in <lambda>(f, *a, **k)
    191     # but it's overkill for just that one bit of state.
    192     def magic_deco(arg):
--> 193         call = lambda f, *a, **k: f(*a, **k)
    194 
    195         if callable(arg):

/projects/sage/sage-6.9/local/lib/python2.7/site-packages/IPython/core/magics/execution.pyc in prun(self, parameter_s, cell)
    273             arg_str += '\n' + cell
    274         arg_str = self.shell.input_splitter.transform_cell(arg_str)
--> 275         return self._run_with_profiler(arg_str, opts, self.shell.user_ns)
    276 
    277     def _run_with_profiler(self, code, opts, namespace):

/projects/sage/sage-6.9/local/lib/python2.7/site-packages/IPython/core/magics/execution.pyc in _run_with_profiler(self, code, opts, namespace)
    295         prof = profile.Profile()
    296         try:
--> 297             prof = prof.runctx(code, namespace, namespace)
    298             sys_exit = ''
    299         except SystemExit:

/projects/sage/sage-6.9/local/lib/python/cProfile.pyc in runctx(self, cmd, globals, locals)
    138         self.enable()
    139         try:
--> 140             exec cmd in globals, locals
    141         finally:
    142             self.disable()

<string> in <module>()

NameError: name 'j' is not defined

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


The line_profiler extension is already loaded. To reload it, use:
  %reload_ext line_profiler
UsageError: Could not find function u'j.generate'.
NameError: name 'j' is not defined

In [ ]:


In [ ]: