Bokeh 0.13 Released

/ Bryan Van de Ven

We are pleased to announce the release of Bokeh 0.13!

Highlights include:

  • Bokeh app components are embeddable in custom templates #4986, #7978
  • New RangeTool added for selecting ranges interactively #7795
  • Max websocket message size now configurable #7374
  • Significant performance improvement for property validation #7977
  • Added cumsum transform to cumulatively sum CDS columns #7961
  • Simplified hover tool usage #7921
  • DataTable regressions fixed #7891, #7924

Plus several other bug fixes and documentation improvements. For full details, see the CHANGELOG and Release Notes. Additionally, examples for each release are uploaded to CDN. Click here to download.

If you are using Anaconda, Bokeh can most easily be installed by executing the command conda install -c bokeh bokeh . Otherwise, use pip install bokeh.

Upcoming 1.0

Bokeh development has reached a point of stability. While there is still plenty of work to be done (expanding test coverage, improving documentation, fixing lots of bugs, and adding new features), the core feature set is largely complete with respect to the original roadmap. Most importantly, the API is now in a place that the core team is happy with and prepared to defend over a longer term. In recognition of this development:

The next release will be Bokeh 1.0

We will spend a short period of time working on some high priority tasks, and making some necessary changes to our build and release infrastructure. We can use help during this time! There will be more frequent 1.0.0dev releases in this time, please help test with them as much as possible. Of course, any code or documentation help is also still very appreciated. Come by the Gitter “Dev” channel and ask about how to get started.

For those curious: the reason for the version bump to 13 now after such a long 0.12.x series is that some build and deployment infrastructure switched over to NumFocus assets, and we wanted to have a clear demarcation of that switchover.

Improved Support for Custom Templates

When Bokeh was started, we had a grand ambition of being able to work purely from Python, “No web-tech required!” To that end we built a layout system that can be used to construct web UIs with rows and columns and grids of things. And it works reasonably well for simple things. If you are prioritizing ease-of-use it can even do for some less simple things. But inevitably, users wanted to use Bokeh for very sophisticated layouts—more sophisticated than the built-in layout can handle.

Until now, only Bokeh standalone documents could flexibly embed individual plots and widgets, using the components function. Bokeh applications were constrained to use only a single top-level Bokeh layout, and this proved to be extremely limiting for users that wished to build sophisticated dashboards with Bokeh. With the release of 0.13.0, it is now possible to embed individual application components as well. As an example, here is a Bokeh app with several components placed individually inside a Bootstrap dashboard layout template:

Image of dash example

In this case we add roots to the document that have a name property set:

plot = figure(..., sizing_mode="scale_both", name="region")


Then, those roots can be referred to in your own Jinja template blocks like this:

<div class="col-md-4 col-sm-4 col-xs-12">
  <div class="x_panel tile fixed_height_320 overflow_hidden">
    <div class="x_title">
      <h2>By Region</h2>
      <div class="clearfix"></div>
    {{ embed(roots.region) }}

You find the code for this example in the GitHub respitory. The User’s Guide also has a new section describing a standard template that anyone can use to quickly get started.

To be sure, there are still issues and kinks to work out. But this advances the possibilities for Bokeh applications a long way, and we look forward to seeing what users come up with!

Range Selection Tool

It’s always nice when a very old issue can be closed, and I am happy to report that the long standing request for a “range” tool has been completed. It is now possible to create a RangeTool to automatically control a range:

# This tool will control the x range on `plot`
range_rool = RangeTool(x_range=plot.x_range)

The tool will display an overlay on the plot it is added to, and this overlay can be dragged and resized to update the range it is configured with. This is often useful for allowing users to zoom in on long time series plots:

It’s also possible to configure the tool with both an x_range and a y_range at the same time, in which case the overlay is a box that can be dragged and resized in both horizontal and vertical directions.

New Cumulative Sum Transform

A new cumsum transform was added to bokeh.transforms. This transform generates a sequence of cumulative sums from the values in a ColumnDataSource column. This can be useful for simplifying any plot that needs to position things based on running totals, such as pie or donut charts:

p.wedge(x=0, y=1, radius=0.4,
        line_color="white", fill_color='color', legend='country', source=data

        # Use a cumulative sum on the angles to compute start/end
        start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'))

Hover Tooltip Improvements

The hover tool has had some limitations in some circumstances in the past. Specfically, users have wanted to display a hover name depending on the glyph that is hovered over. Previously, this would require creating and sending an entire column filled with the name, which is wasteful and redundant. Now, the name property of a glyph may be displayed in a hover tooltip by using the new $name special variable:, name="foo")  # "$name" displays "foo" over these circles, name="bar")  # and displays "bar" over these

Additionally, there were some difficultes with stacked charts. Basically, there was no easy way to have the different glyphs for each stack level refer to different columns. Before, the only way to accomplish this was to create a separate new HoverTool for each stack layer. Now, there is a way to add some indirection, by using the column variable @$name. This syntax means: use the value of $name to specify the column name to display in the tooltip. Stack methods such as vbar_stack also now automatically set name of each renderer to the corresponding stack value, to make things even simpler:

regions = ("East", "Central", "West")

# The glyph for each stack level will set name to a different region,
# and "@$name" will display values from a corresponding column for each
# glyph, e.g. @East, @Central, @North
p.vbar_stack(departments, ...)

Finally, in an effort to streamline the use of hover tools, the figure function now accepts an optional tooltips argument. Supplying tooltips this way will cause a HoverTool to be created and added to the plot (if needed), and configured with those tooltips.

A stacked bar example below demonstrates all of these changes:

fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
years = ["2015", "2016", "2017"]
colors = ["#c9d9d3", "#718dbf", "#e84d60"]

data = {'fruits' : fruits,
        '2015'   : [2, 1, 4, 3, 2, 4],
        '2016'   : [5, 3, 4, 2, 4, 6],
        '2017'   : [3, 2, 4, 4, 5, 3]}

# The "$name" variable shows the hovered glyphs's name property (i.e. a year)
# and the variable "@$name" looks up a column of the same name
p = figure(x_range=fruits, plot_height=250, title="Fruit Counts by Year",
           toolbar_location=None, tools="hover", tooltips="$name @fruits: @$name")

# Each sub-renderer has "name" property set (to a year) automatically
p.vbar_stack(years, x='fruits', width=0.9, color=colors, source=data,
             legend=[value(x) for x in years])

NumFocus Committee Change

When Bokeh was first applying for NumFocus fiscal sponsorship, Jake Vanderplas genererously stepped in to help round out the required project committee. Recently it became possible for long-time Bokeh contributor Luke Canavan to join the committee, so Jake is stepping aside. Thanks Jake, and welcome Luke!

I’d like to thank the 301 total contributors who have helped make Bokeh such an amazing project. If you’re interested in helping out, drop by the Dev Chat Channel!


Bryan Van de Ven