Mandelbrot¶
Download this script from GitHub (right-click to download).
"""
Example app demonstrating how to use the HoloViews API to generate
a bokeh app with complex interactivity. Uses a RangeXY stream to allow
interactive exploration of the mandelbrot set.
"""
import numpy as np
import holoviews as hv
from holoviews import opts
from holoviews.streams import RangeXY
from numba import jit
renderer = hv.renderer('bokeh')
@jit
def mandel(x, y, max_iters):
"""
Given the real and imaginary parts of a complex number,
determine if it is a candidate for membership in the Mandelbrot
set given a fixed number of iterations.
"""
i = 0
c = complex(x,y)
z = 0.0j
for i in range(max_iters):
z = z*z + c
if (z.real*z.real + z.imag*z.imag) >= 4:
return i
return 255
@jit
def create_fractal(min_x, max_x, min_y, max_y, image, iters):
height = image.shape[0]
width = image.shape[1]
pixel_size_x = (max_x - min_x) / width
pixel_size_y = (max_y - min_y) / height
for x in range(width):
real = min_x + x * pixel_size_x
for y in range(height):
imag = min_y + y * pixel_size_y
color = mandel(real, imag, iters)
image[y, x] = color
return image
def get_fractal(x_range, y_range):
(x0, x1), (y0, y1) = x_range, y_range
image = np.zeros((600, 600), dtype=np.uint8)
return hv.Image(create_fractal(x0, x1, -y1, -y0, image, 200),
bounds=(x0, y0, x1, y1))
# Define stream linked to axis XY-range
range_stream = RangeXY(x_range=(-1., 1.), y_range=(-1., 1.))
# Create DynamicMap to compute fractal per zoom range and
# adjoin a logarithmic histogram
dmap = hv.DynamicMap(get_fractal, label='Manderbrot Explorer',
streams=[range_stream]).hist(log=True)
# Apply options
dmap.opts(
opts.Histogram(framewise=True, logy=True, width=200, xlim=(1, None)),
opts.Image(cmap='fire', logz=True, height=600, width=600,
xaxis=None, yaxis=None))
doc = renderer.server_doc(dmap)
doc.title = 'Mandelbrot Explorer'