## Developing Dashboard Applications with Bokeh
*Luke Canavan*
Bokeh seeks to connect PyData tools and users to web-based, interactive visualization
[KeplerGO/lightkurve](https://github.com/KeplerGO/lightkurve)
### Bokeh 1.0 Announcement Features include: * Highly customizable plotting primitives * Interactive plot tools (pan, hover, zoom, etc) * HTML Widgets (sliders, dropdowns, etc) * Native support for network graphs and geo data * Jupyter Notebook, Jupyter Lab, Zeppelin support * JS and Python callbacks on data changes and events * Bokeh Server
### Outline * Building visualizations from primitives * Layouts with bokeh.layouts and custom templates * Styling using Palettes and Themes * Running as a server application
### Goal
### Building visualizations from primitives
Pick what graphical primitives to use, provide the data, and specify how to map visual properties to data fields. Bokeh will take care of the rest.
### Bokeh / BokehJS Architecture
### Using the bokeh.models API ``` $ from bokeh.models import Circle $ circle = Circle(x=5, y=10, fill_color="red") $ circle.to_json(include_defaults=False) > { "angle": { "units": "rad", "value": 0 }, "fill_alpha": { "value": 1 }, "fill_color": { "value": "red" }, "id": "551a8ecc-1059-4478-9ddd-bac1e69f6c76", "js_event_callbacks": {}, "js_property_callbacks": {}, "line_alpha": { "value": 1 }, "line_cap": "butt", "line_color": { "value": "black" }, "line_dash": [], "line_dash_offset": 0, "line_join": "bevel", "line_width": { "value": 1 }, "name": null, "radius": null, "radius_dimension": "x", "size": { "units": "screen", "value": 4 }, "subscribed_events": [], "tags": [], "x": { "value": 5 }, "y": { "value": 7 } } ```
### Write data driven visualizations ``` $ from bokeh.models import ColumnDataSource $ data = { "x": [...], "y": [...], "color": [...]} ### From Dict[str, list] $ source = ColumnDataSource(data) ### From Pandas DataFrame $ df = pd.DataFrame(data) $ source = ColumnDataSource(df) ```
### Map visual properties to data fields ``` $ source = ColumnDataSource({ "x": [...], "y": [...], "color": [...]} $ plot.add_glyph( source, Circle(x='x', y='y', fill_color='color')) ```
To Reiterate: Pick what graphical primitives to use, provide the data, and specify how to map visual properties to data fields. Bokeh will take care of the rest. More reading at [Enjoying the bokeh.models API](https://bokeh.github.io/blog/2017/7/5/idiomatic_bokeh/)
### Face Detection Example
### Layouts with bokeh.layouts and custom templates
Plots and Widgets can be responsive
The bokeh.layouts API offers a "rows and columns"-based layout interface ``` from bokeh.layouts import layouts l = layout([ [bollinger], [sliders, plot], [p1, p2, p3], ], sizing_mode='stretch_both') ```
### Using bokeh.layouts
### Using custom templates * Support for embedding roots into custom Jinja templates * New in Bokeh 0.13.0, you can individually lay out Document items...
Bokeh + CSS Layout Models = Amazing Layouts
[CSS Grid](https://css-tricks.com/snippets/css/complete-guide-grid/)
Dask Distributed's diagnostic UI uses CSS Grid
Dask Distributed's diagnostic UI uses CSS Grid
### Face Detection Example
### Styling using Palettes and Themes
Bokeh offers many aesthetically pleasing color palettes including the Brewer and D3 palettes.
[Made with Holoviews](http://holoviews.org/gallery/demos/bokeh/autompg_violins.html#bokeh-gallery-autompg-violins)
Bokeh also offers perceptually uniform color palettes to allow users to map data to color ranges.
[Made with Datashader](http://datashader.org/getting_started/1_Introduction.html)
Themes are great for maintaining consistent style across several plots ``` attrs: Axis: axis_line_color: "#49483E" axis_label_text_color: "#888888" major_label_text_color: "#888888" major_tick_line_color: "#49483E" minor_tick_line_color: "#49483E" Legend: border_line_color: "#49483E" background_fill_color: "#282828" label_text_color: "#888888" Plot: background_fill_color: "#282828" border_fill_color: "#282828" outline_line_color: "#49483E" ```
Community-created Themes
Caliber
Monokai Dark
Minimal Dark
### Running as a Bokeh server application
Bokeh Server keeps Python and JS models in sync.
Python callbacks can executed on property changes ``` ... def update(attr, old, new): plot.title.text = new x = Select(title='X-Axis', value='mpg', options=columns) x.on_change('value', update) ```
Document-level Python callbacks are intended for server-driven updates like pushes and polling ``` def stream_image(): ... source.data["image"] = [image] doc.add_periodic_callback(acquire_image, 100) ```