from bokeh.io import output_notebook, show
from bokeh.plotting import figure
output_notebook() # alternatively one could use output_file('file_name.html')
import numpy as np
from bokeh.models import BooleanFilter, CDSView, ColumnDataSource as CDS
#create CDS
npoints = 100
dline = dict(x=np.arange(npoints),
y=np.random.normal(0, 0.5, size=npoints),
)
source = CDS(data=dline)
source
#figure options
TOOLS = "pan,hover,box_select,lasso_select,help,reset"
fig_options = dict(plot_width=400, plot_height=400, tools=TOOLS)
#create figure with specifically chosen tools
pleft = figure(**fig_options)
show(pleft)
marker_options = dict(color='red',
fill_color='orange', fill_alpha=0.8)
pleft.triangle('x', 'y', source=source, **marker_options) #pleft.scatter() can be used in a similar way
show(pleft)
#create CDS view (filtered CDS)
#later we will see how to to the same with a JavaScript callback
positives = [True if k>0 else False for k in source.data['y']]
view = CDSView(source=source, filters=[BooleanFilter(positives)])
#create another figure using the view
#notice that the y ranges are being shared
pright = figure(y_range=pleft.y_range, **fig_options)
pright.circle('x', 'y', source=source, view=view, **marker_options)
#introducing layouts
from bokeh.layouts import row
lay = row(pleft, pright)
show(lay)
There are three ways to build interactive plots with bokeh
:
bokeh
serverFirst we will create widgets:
#many widgets available: https://docs.bokeh.org/en/latest/docs/user_guide/interaction/widgets.html
#one can even create a custom widget (advanced): https://docs.bokeh.org/en/latest/docs/user_guide/extensions_gallery/widget.html
from bokeh.models import CustomJS, Slider, Button
button = Button(label="Click!", button_type="warning")
slider = Slider(start=1, end=40, value=5, step=1)
show(row(button, slider))
Let us add some data to the CDS:
def print_cds_columns(s):
for i,col in enumerate(s.data):
print('CDS column #{}: {}'.format(i,col))
source.data['size'] = np.ones(npoints)*10
print_cds_columns(source)
pint = figure(**fig_options)
pint.circle('x', 'y', size='size', source=source, **marker_options)
code = """
var val = slider.value;
var data = s.data;
for (var i = 0; i<data['size'].length; i++) {{
data['size'][i] = val;
}}
s.change.emit();
"""
callback = CustomJS(args=dict(s=source, slider=slider),
code=code)
slider.title = 'Points size'
slider.js_on_change('value', callback)
from bokeh.layouts import layout
lay = layout([slider],[pint])
show(lay)