Bokeh 2.3.3 Page
Even with a stable release, users occasionally encounter issues. Here are common ones and how to solve them:
| 2.3.3 | 3.x |
|-------|-----|
| output_notebook() | Same, but default theme changes |
| from bokeh.palettes import Viridis256 | Use Viridis256 from bokeh.palettes (still works) |
| p.legend.location = "top_left" | p.legend.location = "top_left" (same) |
| p.select_one("type": HoverTool) | p.select(type=HoverTool) (deprecation) |
from bokeh.io import export_png, export_svg, save
save(p, "plot.html") # interactive HTML export_png(p, "plot.png") # requires selenium + phantomjs (older)bokeh 2.3.3
In 2.3.3,
export_pngmay need manual setup. Usesave()for reliable sharing. Even with a stable release, users occasionally encounter
layout = row(column(p, width=850), data_table)
If you're starting a new project today, should you use Bokeh 2.3.3 or jump to Bokeh 3.4+? Here’s a decision matrix: from bokeh
| Feature / Consideration | Bokeh 2.3.3 | Bokeh 3.x+ | |-------------------------------|--------------------------------------------------|------------------------------------------------| | Python version support | 3.6 – 3.9 (3.10 experimental) | 3.8 – 3.11+ | | API stability | Frozen, no changes | Evolving (removals up to 3.4) | | New features | No | Yes (e.g., Vega themes, better TypeScript) | | Long-term support | Community, no official LTS | Active development | | Legacy code compatibility | Excellent | May require refactoring (layouts, tools) | | Security patches | No new patches | Regular |
Recommendation: Stick with Bokeh 2.3.3 if you have a working production system that you don't want to risk breaking. Choose Bokeh 3.x for greenfield projects where you can adopt the latest patterns.
| Problem | Fix |
|---------|-----|
| Jupyter plot not showing | Use output_notebook() before show(). |
| HoverTool shows ??? | Ensure tooltips use field names matching ColumnDataSource columns. |
| Layout breaks | Use sizing_mode="stretch_width" or "stretch_both" on top-level layout. |
| Widgets not updating | Check that CustomJS uses source.change.emit(). |