We will briefly examine another one of the demo applications hosted on the demo.bokeh.org website, namely the Movies application, which presents an Interactive Explorer for Movie Data. We will only examine part of the associated source code, to focus more on the different types of widgets used in the GUI.
We first present a screenshot of part of the movies application.
A screenshot demonstrating part of the movies application hosted at demo.bokeh.org, where various widgets provide interactive tools to customize plotted data.
The source code for the movies application is provided as part of the Bokeh demo site, and can be found at in the Bokeh github repository. We will not reproduce all of that source code here, but we include some key parts to focus on. The line numbers have been added to the presentation to facilitate discussion of the code:
from bokeh.io import curdoc
from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource, Div, Select, Slider, TextInput
from bokeh.plotting import figure
from bokeh.sampledata.movies_data import movie_path
# ... skip some lines of code# Create Input controls
reviews = Slider(title="Minimum number of reviews", value=80, start=10, end=300, step=10)
min_year = Slider(title="Year released", start=1940, end=2014, value=1970, step=1)
max_year = Slider(title="End Year released", start=1940, end=2014, value=2014, step=1)
oscars = Slider(title="Minimum number of Oscar wins", start=0, end=4, value=0, step=1)
boxoffice = Slider(title="Dollars at Box Office (millions)", start=0, end=800, value=0, step=1)
genre = Select(title="Genre", value="All",
options=open(join(dirname(__file__),'genres.txt')).read().split())
director = TextInput(title="Director name contains")
cast = TextInput(title="Cast names contains")
x_axis = Select(title="X Axis", options=sorted(axis_map.keys()), value="Tomato Meter")
y_axis = Select(title="Y Axis", options=sorted(axis_map.keys()), value="Number of Reviews")# ... skip some more lines of code
controls =[reviews, boxoffice, genre, min_year, max_year, oscars, director, cast, x_axis, y_axis]for control in controls:
control.on_change('value',lambda attr, old, new: update())
inputs = column(*controls, width=320, height=800)
layout = column(desc, row(inputs, p, sizing_mode="inherit"), sizing_mode="stretch_width", height=800)
update()# initial load of the data
curdoc().add_root(layout)
curdoc().title ="Movies"
Python
The section commented as "# Create Input controls" (lines 10-20) creates a number of different widget objects to support user interactions. Each time any of these widgets is changed, an update callback function is called (lines 24-26).
Several of these are Sliders, that can be used to slide through a specified range of values (from start to end), and which are initialized with a default value.
Several of these are Select widgets, which we examined previously in the context of the Crossfilter application.
Two of these are TextInput widgets, which capture whatever text is entered into the box.
Finally, once all the widgets are created, they are laid out in a column in the GUI (lines 28-30). The layout configuration also includes information about how the components and the GUI is sized to accommodate browser windows of different sizes.