Bokeh Journal

News and updates for all things Bokeh.

Bokeh 1.1.0 Released

09 April 2019

We are pleased to announce the release of Bokeh 1.1!

The major topic for this release was improving Bokeh’s layout capability. More than 50 layout related issues were closed! In addition to the layout overhaul, many other small bugfixes and features went into this release. Some highlights:

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.


Layout Overhaul

One of the last major areas Bokeh has needed improvement in is its layout system. For several years, Bokeh used a constraint solver to compute the layout positions of plots, axes, widgets, etc. The constraint-based approach initially promised to afford a very sophisticated layout capability with a very general approach across the library. Ultimately, it suffered from many intrinsic practical issues, some of which are discussed below.

Bokeh 1.1 contains a major overhaul of the layout system by Mateusz Paprocki that removes the constraint-based approach entirely, in favor of a simpler, more predictable, more testable alogrithm. All of this brings many benefits, as well as dozens of fixed issues.

Layout Performance

While we hadn’t originally imagined users putting many dozens or hundreds of plots on a single page, it is a topic that has been raised several times over the years. Unfortunately a major drawback with the constraint-based approach to layout is that its scaling behavior made these kinds of use-cases impossibly slow. The 60-plot test case in #6294 took nearly 40 seconds(!) to load.

With this work, layout computation (even for large cases) typically takes only a few milliseconds. The test case in the issue above now loads in under one second. I’m happy to report that even pages with hundreds of plots are now possible:

Image of large grid plot

To see the full 260 plots load in ~2 seconds, click here.

As part of this work some excessive over-rendering was also cleaned up, leading to improvements in other areas, such as DataTable performance. In general Bokeh should seem snappier across the board with this release.

Sizing Modes

Another drawback of the constraint-based approach was that it was hard to develop features around. It had some nice qualities for the simplest cases, but made even slightly more complicated situations more difficult than they needed to be. As a result, several of the sizing modes we had imagined having available were either broken, or not implemented fully. I am happy to report that all the sizing modes such as "stretch_both" and "scale_width" are now implemented fully:

Animated image of large sizing modes

Testing Improvements

A final drawback to the constraint-based approach is that it was difficult to debug and maintain. When things went wrong, there was very little actionable information available. Beyond that, it was difficult to create tests that thoroughly exercised layout. As a result it was far too easy to make code updates that left undetected and unintentional changes.

As part of this work, a very large suite of “baseline” tests that record exact pixel dimensions of layouts was added. These tests cover all of our examples and documentation, as well as many purpose-written scripts that exercise very specific layout situations. The layout record is a simple text format that can be quickly and easily diffed in unit tests.

Although there are no exciting images or plots in this section, this is probably one of the most important outcomes of the “Big Layout Refector”. With this new testing infrastructure in place, we can be certain that if there are changes to make in the future, they will be considered and intentional.


This work marks the largest update since Bokeh 1.0. We made a strong effort to ensure no APIs or behaviors changed in incompatible ways. But with limited resources, it’s possible things slipped by. Please raise GitHub issues if any problems arise. If you’d like to help increase the testing that Bokeh receives, for the benefit of all users, please reach out.

Two New Widgets

Two new widgets were added in Bokeh 1.1: a numeric input with configurable step size, and a color selector. Use the widgets to change the color and size of the scatter markers below:

 

Note that the color selector is currently browser dependent. Some browsers show a sophisticated color picker, others display a simple hex color input. Integrating a third party color picker that is consistent across platforms would make a great task for anyone looking to get involved in Bokeh core development.

It’s also worth mentioning the new js_link feature that makes hooking up properties to widgets easier than ever. For the sample above, the widget size spinner can be connected with a single call to js_link, no CustomJS needed:

r = p.circle(...)
spinner = Spinner(title="Glyph size", ...)
spinner.js_link('value', r.glyph, 'size')

RGBA Image Hover

Some time ago, hover tool capabilities were added to the colormapped Image glyph. For uninteresting reasons, the same capability was not added to the ImageRGBA glyph at that time. However, with this release, it is now possible to have hover tooltips on RGBA images:

 

In this case we used a CustomJSHover to format the color channels:

code = """
const r = (value >> 0 ) & 255
const g = (value >> 8 ) & 255
const b = (value >> 16) & 255
return `(${r}, ${g}, ${b})`
"""

HoverTool(
    tooltips=[
        ( '(x, y)',  '$x, $y'         ),
        ( '(r,g,b)', '@image{custom}' ),
    ],
    formatters={ 'image' : CustomJSHover(code=code) }
)

Call to Action

With my departure from Anaconda, the development on Bokeh enters a new, more leisurely phase. Happily, most of the heavy lifting has been accomplished. But there is still ongoing work to do, and now marks a time when there is opportunity for anyone to make a big positive impact. Here are some ways you can help the entire Bokeh community:

Bokeh relies on paid cloud infrastucture to host the CDN files for BokehJS, serve the documentation and demos, and store CI build artifacts. Your contribution to NumFocus helps defray those costs.

Become a new contributor

With fewer people paid to work on Bokeh, it’s more important than ever for new contributors to step up. Code contributions are always welcome, but there are actually other areas that the project team lacks depth, where new people with a little experience could make a huge difference:

  • Cloud infra management (AWS and Azure) to streamline operations
  • Web and graphic design to improve the docs, demo, and sharing sites
  • Technical writing to improve the Information Architecture of the docs
  • Front-end dev to help make BokehJS a real JS library on its own
  • Selenium testing to increase reliability and stability across releases
  • SEO/Site analytics to help understand and improve our web properties
  • Grant writing to help pursue new funding opportunities

As you can imagine, there is no way for the current small core team to handle all of these tasks at once, let alone be expert in all of them. A little bit of your expertise will go a long way, for an entire community of users!

Offer support help

This is really another form of contribution, but it’s worth drawing out explicitly. There is a great combined wealth of knowledge about Bokeh in the community. If many people make a small effort to help others on the mailing list and Stack Overflow, then everyone benefits and no one has to shoulder too much burden. Please consider sharing your valuable knowledge with other users. To help make things easier, we hope to move Bokeh community support to a Discourse instance later this year.


As always, anyone interested in helping out should drop by the Dev Chat Channel! and say hello!

Thanks,

Bryan Van de Ven