Holoviews cheatsheet


In [1]:
import pandas as pd
import numpy as np
import holoviews as hv
from holoviews import opts
from holoviews import streams
import param
hv.extension('bokeh')#, 'matplotlib')

# Set dark theme
from bokeh.themes import built_in_themes
hv.renderer('bokeh').theme = built_in_themes['dark_minimal']


Setting default figure size


In [2]:
# Set default figure size on curves
opts.defaults(opts.Curve( height=400, width=900 ,show_grid=True))

In [3]:
x = np.linspace(0,4*np.pi)
y = np.cos(x)

wave = hv.Curve((x, y), ('x','x axis'), ('y','y axis'))
wave


Out[3]:

In [4]:
print(wave)


:Curve   [x]   (y)

Setting default theme in Bokeh


In [ ]:
from bokeh.themes.theme import Theme

theme = Theme(
    json={
'attrs' : {
    'Title':{
        'text_color': "white",
    },
    'Figure' : {
        'background_fill_color': '#2F2F2F',
        'border_fill_color': '#2F2F2F',
        'outline_line_color': '#444444',
    },
    'Grid': {
        'grid_line_dash': [6, 4],
        'grid_line_alpha': .3,
    },

    'Axis': {
        'major_label_text_color': 'white',
        'axis_label_text_color': 'white',
        'major_tick_line_color': 'white',
        'minor_tick_line_color': 'white',
        'axis_line_color': "white"
    },
    'Legend':{
        'background_fill_color': 'black',
        'background_fill_alpha': 0.5,
        'location' : "center_right",
        'label_text_color': "white"
    }
}
})

hv.renderer('bokeh').theme = theme

In [ ]:
wave

Stacking plots


In [ ]:
# Set default figure size on curves
# and turn on grid
opts.defaults(opts.Curve( height=200, width=300, show_grid=True))

In [ ]:
# Generate 4 plots
x = np.linspace(0,4*np.pi,100)

Nplots = 4
waves = []
for iP in range(Nplots):
    y = np.cos((iP+1)*x)
    waves.append( hv.Curve((x, y), ('x','x axis'), ('y','y axis'),label='Plot %i' % iP))

In [ ]:
# Stack plots individually in a row
hv.Layout(waves)

In [ ]:
# Stack plots in a column
hv.Layout(waves).cols(1)

In [ ]:
# Stack plots in 2 columns
hv.Layout(waves).cols(2)

Overlay curves on one plot


In [ ]:
hv.Overlay(waves)

In [ ]:
# Increase size of plot locally
hv.Overlay(waves).opts(opts.Curve(height=400,width=800))

In [ ]:
# Set legend position
# options are: [top_right, top_left, bottom_left, bottom_right, right, left, top, bottom]
# Also turn on grid and hover tooltips
hv.Overlay(waves).opts(opts.Curve(height=400,width=800,show_grid=True, tools=['hover'])).opts(legend_position='right',title='Plot with legend on right')

Getting help


In [ ]:
hv.help(hv.Curve)

In [ ]:
hv.help(hv.Overlay)

Using Datashader


In [ ]:
from holoviews.operation.datashader import datashade, shade, dynspread, rasterize
from holoviews.operation import decimate

In [ ]:
np.random.seed(1)
points = hv.Points(np.random.multivariate_normal((0,0), [[0.1, 0.1], [0.1, 1.0]], (1000,)),label="Points")

points

In [ ]:
datashade(points)

Selection


In [ ]:
import numpy as np
import holoviews as hv
from holoviews.streams import Selection1D

renderer = hv.renderer('bokeh')
hv.opts("Points [tools=['box_select']]")

data = np.random.multivariate_normal((0, 0), [[1, 0.1], [0.1, 1]], (1000,))
points = hv.Points(data)
sel = Selection1D(source=points)
mean_sel = hv.DynamicMap(lambda index: hv.HLine(points.iloc[index]['y'].mean()
                                                if index else -10),
                         kdims=[], streams=[sel])

#doc = renderer.server_doc(points * mean_sel)
#doc.title = 'HoloViews Selection Stream'
points * mean_sel

In [ ]:
index =[0,10,20,30,40]
points.iloc[index]

Box select

Using DynamicMap to create a box that follows the dimensions of the box_select tool


In [ ]:
bbox = []

def draw_box(bounds):
    global bbox
    
    if bounds is not None:
        left, bottom, right, top = bounds

        x = (left + right)/2
        y = (top + bottom)/2
        w = abs(left-right)
        h = abs(top-bottom)
        
        bbox = [x,y,w,h]

        return hv.Box(x,y,(w,h)).opts(color='red',line_width=5) 
    
    return hv.Box(1,1,0.5,width=0.5).opts(color='gray',line_width=5) 

box_select = hv.streams.BoundsXY()

dmap = hv.DynamicMap(draw_box,kdims=[],streams=[box_select])
dmap.opts(xlim=(0,10),ylim=(0,10))

In [ ]:
bbox

In [ ]:
hv.help(hv.Box)

Superimposing the box drawing onto an image


In [ ]:
xvals = np.linspace(0,10,202)
ys,xs = np.meshgrid(xvals, xvals[::-1])
#img = hv.Image(np.sin(((ys)**3)*xs))

img = hv.Image( (xvals,xvals,np.sin(((ys)**3)*xs)) )

(img * dmap).opts(xlim=(0,10),ylim=(0,10))
#img

Streams


In [ ]:
listing = ', '.join(sorted([str(s.name) for s in param.descendents(streams.LinkedStream)]))
print('The linked stream classes supported by HoloViews are:\n\n{listing}'.format(listing=listing))

In [ ]:
hv.help(streams.BoundsXY)

In [ ]:
pointer = streams.PointerXY()
pointer_dmap = hv.DynamicMap(lambda x, y: hv.Points([(x, y)]), streams=[pointer])
print(pointer.source is pointer_dmap)
pointer_dmap.opts(size=10)

In [ ]:
xvals = np.linspace(0,4,202)
vals = np.linspace(0,4,202)
ys,xs = np.meshgrid(xvals, -xvals[::-1])
img = hv.Image(np.sin(((ys)**3)*xs))

pointer = streams.PointerXY(x=0,y=0, source=img)
pointer_dmap = hv.DynamicMap(lambda x, y: hv.Points([(x, y)]), streams=[pointer])
pointer_dmap = pointer_dmap.redim.range(x=(-0.5,0.5), y=(-0.5,0.5))

In [ ]:
img + pointer_dmap.opts(size=10)

In [ ]:
x_sample = hv.DynamicMap(lambda x, y: img.sample(x=np.clip(x,-.49,.49)), streams=[pointer])
y_sample = hv.DynamicMap(lambda x, y: img.sample(y=np.clip(y,-.49,.49)), streams=[pointer])

(x_sample + y_sample).opts(opts.Curve(framewise=True))

Dynamic Map


In [2]:
frequencies = [0.5, 0.75, 1.0, 1.25]

def sine_curve(phase, freq):
    xvals = [0.1* i for i in range(100)]
    return hv.Curve((xvals, [np.sin(phase+freq*x) for x in xvals]))

# When run live, this cell's output should match the behavior of the GIF below
dmap = hv.DynamicMap(sine_curve, kdims=['phase', 'frequency'])
dmap.redim.range(phase=(0.5,1), frequency=(0.5,1.25))


Out[2]:

END