10

Chapter 10 · Python

Python: Bokeh

Matplotlib and Seaborn produce images. Bokeh produces web objects the reader can zoom, pan, hover and filter. That difference is what turns an author-driven chart into the hybrid narrative from Chapter 6.

1What Bokeh is

  1. A Python library for interactive visualisations that run in a web browser.
  2. It generates the JavaScript for you. You never write JavaScript.
  3. Scales from a single plot to a full dashboard, and can handle live streaming data.
  4. Three output targets: a standalone HTML file, a plot inside a notebook, or a server application.
Why it belongs in this course

Chapter 6 placed narratives on a spectrum from author-driven to reader-driven, with the hybrid in between. Bokeh is how you build the hybrid in Python: you fix the structure and the story, and the audience explores inside it and draws its own conclusions.

pip install bokeh          # or: conda install bokeh

from bokeh.io import output_notebook
output_notebook()          # call ONCE per notebook, enables inline output

Two interfaces

InterfaceLevelUse for
bokeh.plottingHigh level, the primary interfaceStandard charts. Handles styling and defaults for you
bokeh.modelsLow levelFull control when you need a custom visual

Work in bokeh.plotting and drop into bokeh.models only when you need a specific component, such as a hover tool or a widget. This is the same trade as low-code against code-based tools from Chapter 5, inside one library.

The core workflow

Fig 10.1Three steps, and show(p) is not optional

You must call show(). Unlike Matplotlib in a notebook, nothing renders on its own, and every Bokeh plot ends with show(p).

Glyphs

A glyph is the visual mark representing the data. In Bokeh's vocabulary, the line you plot is a glyph, and so is every circle, bar and wedge.

Fig 10.2Multiple glyphs stack onto the same figure
Call several glyph methods on the same p before calling show, and they all appear on one figure. Common marker names are "circle", "square", "triangle", "asterisk" and "circle_dot".

Categorical bar charts, and why x_range matters

Fig 10.3The one line that tells Bokeh the axis is categorical

x_range= is what tells Bokeh the axis is categorical, not continuous. Without it the axis is treated as numbers and the chart fails. major_label_orientation rotates tick labels when names are long, and since Chapter 3 preferred horizontal text, use it only when abbreviating is not possible.

Interactivity you get for free

Fig 10.4The default toolbar, working. Drag, scroll, box zoom, reset

None of this required any code. That is Bokeh's main argument: the interactivity that Chapter 5 said defines a dashboard is the default rather than something you build.

Pan drags the plot around, box zoom zooms into a selected rectangle, wheel zoom uses the scroll wheel, save downloads the plot as a PNG and reset returns to the original view. Try zooming into the dense cluster at the bottom left: on a static image that cluster is one blob forever.

Clickable legends

Fig 10.5Click a legend entry. One line of Python does this
click_policy

click any legend entry above

The reader filters the chart by clicking the legend. "hide" removes the series and "mute" fades it instead, which keeps it as context rather than deleting it. This is reader-driven narrative in one line.

ColumnDataSource

Bokeh's core data structure, and the thing that makes hover tools and linked plots work.

Fig 10.6Columns by name, and what that buys you

A ColumnDataSource maps column names to sequences of values, and every column must be the same length, which is the usual source of errors. Once data is in one, glyphs reference columns by name rather than by value, and that is what lets extra columns be carried along for tooltips.

The hover tool

Fig 10.7Build the tooltip, then hover a point
tooltip fields
@column_name refers to a column in the ColumnDataSource, and $index is a Bokeh special field holding the row number. Chapter 4 said bar length supports detection and ranking but weak estimation. A hover tooltip supplies the exact number the eye cannot measure, so hover repairs the known weakness of the encoding. That is the same argument Chapter 5 made about dashboard pop-ups.

Widgets

Fig 10.8A date range slider, doing what a date range slider does
from bokeh.models import DateRangeSlider

date_range_slider = DateRangeSlider(
    value=(date(2022, 10, 1), date(2022, 12, 31)),
    start=(date(2022, 7, 1)), end=(date(2023, 3, 31)))

A date range slider lets the reader pick a period and see the phenomenon for just that range. It is useful whenever the full series is too long to read at once, for example a financial year you want to view a quarter at a time.

This is audience narrative control: the reader runs their own analysis inside the frame you built.

Compare the whole-year view against a single quarter. The quarter is not new data, it is the same series with the reader's own question applied to it, and neither view is more correct than the other.

Layouts

Fig 10.9row, column and gridplot
A Bokeh document can hold one plot or many arranged into a layout. This is the small multiples idea from Chapter 2 and the faceting from Chapter 9, with one addition: each panel keeps its own interactivity. Compared with Seaborn's col= and row=, Bokeh needs you to build each plot yourself, and gives you zoom and hover on every panel in return.

Decorating the visuals

Four ways to specify a colour

"green" one of 140 CSS names · "#2e8b57" hex · (0, 100, 100) three-tuple RGB · (100, 100, 100, 0.85) four-tuple RGBA, where the fourth value is alpha from 0 to 1.

Alpha is transparency. Lowering it lets overlapping marks show through, which matters on dense scatter plots.

Four visual property families

TEXT text_font_size text_color
LINE line_width line_color line_alpha line_dash
FILL fill_color fill_alpha
HATCH hatch_color hatch_alpha hatch_pattern

The consistency is the point: once you know line_color and fill_alpha, the same names work on every glyph in the library.

Fig 10.10Alpha on a dense scatter

Removing gridlines and axes you do not need is Chapter 3's decluttering, expressed in Bokeh syntax through p.grid.grid_line_color = None. Because a hover tooltip can supply exact values, you can often drop more furniture here than in a static chart. Bokeh also supports themes, which are the same idea as Matplotlib style sheets from Chapter 7.

The three libraries compared

MatplotlibSeabornBokeh
OutputStatic imageStatic imageInteractive web object
LevelLowHigh, statisticalHigh, with low-level models available
StrengthTotal controlStatistics and defaults handledInteractivity and browser delivery
Best forExploration, fine customisationStatistical charts for reportsDashboards and shared exploration
Data inputArrays, SeriesDataFrame via data=ColumnDataSource

Choose by the delivery format. A printed report wants Seaborn. A chart somebody will interrogate wants Bokeh.

Key points

  1. What Bokeh produces that Matplotlib and Seaborn do not.
  2. Its three output targets.
  3. How Bokeh delivers the hybrid narrative from Chapter 6.
  4. output_notebook(), and that it is called once per notebook.
  5. bokeh.plotting against bokeh.models.
  6. The three-step workflow, and that show() is mandatory.
  7. What a glyph is, and how multiple glyphs stack on one figure.
  8. Why x_range= is needed for a categorical bar chart.
  9. The five default toolbar tools.
  10. legend.click_policy, and what "hide" and "mute" do.
  11. ColumnDataSource: what it maps, and the equal-length rule.
  12. HoverTool tooltips, @column against $index, and why hover compensates for weak estimation.
  13. What a widget such as a date range slider gives the reader.
  14. row, column and gridplot, and how they relate to small multiples.
  15. Four ways to specify a colour, and what alpha controls.
  16. The four visual property families.
  17. When to choose Matplotlib, Seaborn or Bokeh.