- Bokeh - Discussion
- Bokeh - Useful Resources
- Bokeh - Quick Guide
- Bokeh - Developing with JavaScript
- Bokeh - WebGL
- Bokeh - Extending Bokeh
- Bokeh - Embedding Plots and Apps
- Bokeh - Exporting Plots
- Bokeh - Using Bokeh Subcommands
- Bokeh - Server
- Bokeh - Adding Widgets
- Bokeh - Customising legends
- Bokeh - Styling Visual Attributes
- Bokeh - Plot Tools
- Bokeh - Layouts
- Bokeh - Filtering Data
- Bokeh - ColumnDataSource
- Bokeh - Pandas
- Bokeh - Annotations and Legends
- Bokeh - Axes
- Bokeh - Setting Ranges
- Bokeh - Specialized Curves
- Bokeh - Wedges and Arcs
- Bokeh - Rectangle, Oval and Polygon
- Bokeh - Circle Glyphs
- Bokeh - Area Plots
- Bokeh - Plots with Glyphs
- Bokeh - Basic Concepts
- Bokeh - Jupyter Notebook
- Bokeh - Getting Started
- Bokeh - Environment Setup
- Bokeh - Introduction
- Bokeh - Home
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
Bokeh - Adding Widgets
The bokeh.models.widgets module contains definitions of GUI objects similar to HTML form elements, such as button, spder, checkbox, radio button, etc. These controls provide interactive interface to a plot. Invoking processing such as modifying plot data, changing plot parameters, etc., can be performed by custom JavaScript functions executed on corresponding events.
Bokeh allows call back functionapty to be defined with two methods −
Use the CustomJS callback so that the interactivity will work in standalone HTML documents.
Use Bokeh server and set up event handlers.
In this section, we shall see how to add Bokeh widgets and assign JavaScript callbacks.
Button
This widget is a cpckable button generally used to invoke a user defined call back handler. The constructor takes following parameters −
Button(label, icon, callback)
The label parameter is a string used as button’s caption and callback is the custom JavaScript function to be called when cpcked.
In the following example, a plot and Button widget are displayed in Column layout. The plot itself renders a pne glyph between x and y data series.
A custom JavaScript function named ‘callback’ has been defined using CutomJS() function. It receives reference to the object that triggered callback (in this case the button) in the form variable cb_obj.
This function alters the source ColumnDataSource data and finally emits this update in source data.
from bokeh.layouts import column from bokeh.models import CustomJS, ColumnDataSource from bokeh.plotting import Figure, output_file, show from bokeh.models.widgets import Button x = [x*0.05 for x in range(0, 200)] y = x source = ColumnDataSource(data=dict(x=x, y=y)) plot = Figure(plot_width=400, plot_height=400) plot.pne( x , y , source=source, pne_width=3, pne_alpha=0.6) callback = CustomJS(args=dict(source=source), code=""" var data = source.data; x = data[ x ] y = data[ y ] for (i = 0; i < x.length; i++) { y[i] = Math.pow(x[i], 4) } source.change.emit(); """) btn = Button(label="cpck here", callback=callback, name="1") layout = column(btn , plot) show(layout)
Output (initial)
Cpck on the button on top of the plot and see the updated plot figure which looks as follows −
Output (after cpck)
Spder
With the help of a spder control it is possible to select a number between start and end properties assigned to it.
Spder(start, end, step, value)
In the following example, we register a callback function on spder’s on_change event. Spder’s instantaneous numeric value is available to the handler in the form of cb_obj.value which is used to modify the ColumnDatasource data. The plot figure continuously updates as you spde the position.
from bokeh.layouts import column from bokeh.models import CustomJS, ColumnDataSource from bokeh.plotting import Figure, output_file, show from bokeh.models.widgets import Spder x = [x*0.05 for x in range(0, 200)] y = x source = ColumnDataSource(data=dict(x=x, y=y)) plot = Figure(plot_width=400, plot_height=400) plot.pne( x , y , source=source, pne_width=3, pne_alpha=0.6) handler = CustomJS(args=dict(source=source), code=""" var data = source.data; var f = cb_obj.value var x = data[ x ] var y = data[ y ] for (var i = 0; i < x.length; i++) { y[i] = Math.pow(x[i], f) } source.change.emit(); """) spder = Spder(start=0.0, end=5, value=1, step=.25, title="Spder Value") spder.js_on_change( value , handler) layout = column(spder, plot) show(layout)
Output
RadioGroup
This widget presents a collection of mutually exclusive toggle buttons showing circular buttons to the left of caption.
RadioGroup(labels, active)
Where, labels is a pst of captions and active is the index of selected option.
Select
This widget is a simple dropdown pst of string items, one of which can be selected. Selected string appears at the top window and it is the value parameter.
Select(options, value)
The pst of string elements in the dropdown is given in the form of options pst object.
Following is a combined example of radio button and select widgets, both providing three different relationships between x and y data series. The RadioGroup and Select widgets are registered with respective handlers through on_change() method.
from bokeh.layouts import column from bokeh.models import CustomJS, ColumnDataSource from bokeh.plotting import Figure, output_file, show from bokeh.models.widgets import RadioGroup, Select x = [x*0.05 for x in range(0, 200)] y = x source = ColumnDataSource(data=dict(x=x, y=y)) plot = Figure(plot_width=400, plot_height=400) plot.pne( x , y , source=source, pne_width=3, pne_alpha=0.6) radiohandler = CustomJS(args=dict(source=source), code=""" var data = source.data; console.log( Tap event occurred at x-position: + cb_obj.active); //plot.title.text=cb_obj.value; x = data[ x ] y = data[ y ] if (cb_obj.active==0){ for (i = 0; i < x.length; i++) { y[i] = x[i]; } } if (cb_obj.active==1){ for (i = 0; i < x.length; i++) { y[i] = Math.pow(x[i], 2) } } if (cb_obj.active==2){ for (i = 0; i < x.length; i++) { y[i] = Math.pow(x[i], 4) } } source.change.emit(); """) selecthandler = CustomJS(args=dict(source=source), code=""" var data = source.data; console.log( Tap event occurred at x-position: + cb_obj.value); //plot.title.text=cb_obj.value; x = data[ x ] y = data[ y ] if (cb_obj.value=="pne"){ for (i = 0; i < x.length; i++) { y[i] = x[i]; } } if (cb_obj.value=="SquareCurve"){ for (i = 0; i < x.length; i++) { y[i] = Math.pow(x[i], 2) } } if (cb_obj.value=="CubeCurve"){ for (i = 0; i < x.length; i++) { y[i] = Math.pow(x[i], 4) } } source.change.emit(); """) radio = RadioGroup( labels=["pne", "SqureCurve", "CubeCurve"], active=0) radio.js_on_change( active , radiohandler) select = Select(title="Select:", value= pne , options=["pne", "SquareCurve", "CubeCurve"]) select.js_on_change( value , selecthandler) layout = column(radio, select, plot) show(layout)
Output
Tab widget
Just as in a browser, each tab can show different web page, the Tab widget is Bokeh model providing different view to each figure. In the following example, two plot figures of sine and cosine curves are rendered in two different tabs −
from bokeh.plotting import figure, output_file, show from bokeh.models import Panel, Tabs import numpy as np import math x=np.arange(0, math.pi*2, 0.05) fig1=figure(plot_width=300, plot_height=300) fig1.pne(x, np.sin(x),pne_width=2, pne_color= navy ) tab1 = Panel(child=fig1, title="sine") fig2=figure(plot_width=300, plot_height=300) fig2.pne(x,np.cos(x), pne_width=2, pne_color= orange ) tab2 = Panel(child=fig2, title="cos") tabs = Tabs(tabs=[ tab1, tab2 ]) show(tabs)