English 中文(简体)
Bokeh - Adding Widgets
  • 时间:2024-11-03

Bokeh - Adding Widgets


Previous Page Next Page  

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)

Button

Cpck on the button on top of the plot and see the updated plot figure which looks as follows −

Output (after cpck)

Button After

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

Spder

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

Select Select

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)

Output

Tab widget Advertisements