Bokeh
Interactive visualization library for building browser-based plots, dashboards, and data apps from Python.
Repository Health
Technical Analysis
Bokeh is a Python library for creating interactive, browser-rendered visualizations without writing JavaScript. It pairs a Pythonic plotting API with BokehJS, a companion TypeScript rendering engine, so charts built in Python become fully interactive in the browser — panning, zooming, hovering, and linked selections all work out of the box.
Beyond static charts, Bokeh includes a server component (built on Tornado/ASGI) for building live data applications where Python callbacks update the browser in real time, making it a common choice for dashboards, streaming-data monitors, and exploratory tools embedded in Jupyter notebooks or standalone web apps.
What You Get
- A high-level
figure()plotting API covering line, bar, scatter, patch, image, and geographic glyphs with sensible defaults - A lower-level, fully declarative model/property system for building custom visualizations glyph-by-glyph
- BokehJS, a standalone TypeScript rendering engine that runs visualizations client-side with WebGL acceleration for large datasets
- A built-in application server (Tornado/ASGI) for live, bidirectional dashboards where Python code reacts to browser interactions
- Export to static HTML, standalone JSON, or PNG/SVG images via Selenium
- Native output support inside Jupyter notebooks and JupyterLab
Common Use Cases
- Building interactive dashboards for exploring large or streaming datasets in a browser
- Embedding interactive plots in a data science notebook without leaving Python
- Serving live-updating data applications where user interaction triggers Python-side computation
- Producing standalone HTML visualizations for reports or web pages with no server required
- Visualizing geospatial data with interactive maps and tile providers
Under The Hood
Architecture
Bokeh separates concerns cleanly across several layers: a core property/model system (bokeh.core, has_props.py, properties/) defines a declarative, strongly-typed scene graph; a high-level plotting API (bokeh.plotting, centered on _figure.py) builds that graph from simple calls like figure().line(...); a serialization layer (bokeh.document, bokeh.core.serialization) turns the model graph into JSON; and bokeh.server (Tornado/ASGI-based, with session.py and callbacks.py) keeps a live Python-side document synchronized with a browser session over a websocket protocol. BokehJS, a separate TypeScript codebase under bokehjs/, consumes that same JSON model representation to render and interact with plots independently of the Python process, so a chart can run as static HTML with no server at all, or as a fully live application. This split between a portable declarative model and two independent renderers (Python-side construction, JS-side rendering) is the architecture’s defining trait, and it is what lets the same visualization be exported to plain HTML or driven live from a running server.
Tech Stack
Bokeh targets Python 3.12+ and depends on numpy, jinja2, pyyaml, packaging, pillow, and xyzservices for tile providers, with tornado powering the built-in server on non-emscripten platforms. Optional extras add pandas/contourpy for richer data handling and selenium for static image export. The client side is an entirely separate TypeScript codebase (BokehJS, roughly half the repository’s source by byte count) built with its own tooling and shipped to npm as @bokeh/bokehjs, with WebGL and GLSL used for accelerated rendering of large datasets. Development uses pixi for environment management and setuptools-git-versioning for dynamic version derivation from git tags.
Code Quality
The project has an extensive test suite split into tests/unit, tests/integration, and tests/cross (Python-vs-BokehJS cross-validation), run under pytest with custom markers for concurrency and Selenium-dependent tests. Typing is strict: mypy --strict is configured across src/bokeh, tools, and tests, backed by hand-maintained .pyi stub files for the plotting API. Linting runs through ruff, and CI (bokeh-ci.yml, bokeh-ci-full.yml, bokehjs-ci.yml, plus CodeQL analysis) exercises both the Python and TypeScript halves of the codebase on every change, along with dedicated visual-regression and example-execution tests.
API Design
The plotting API favors a small, consistent surface: nearly every glyph type is a method on a single figure object with shared, predictable keyword conventions for styling and data sources, which keeps the learning curve low for common charts. Power users can drop down to the declarative model layer for full control without switching libraries or mental models — the same property system underlies both. The tradeoff is a large surface area once server apps, custom extensions, and the full model hierarchy are in play, but extensive first-steps guides, hundreds of runnable examples, and generated API docs keep the onboarding path well-supported.