Share a Bokeh plot

Bokeh has two modes and only one of them travels. A Bokeh server app has a Python process behind every widget callback. A Bokeh standalone document is one HTML file that carries its own data and its own JavaScript — it works from any static host, or from an email attachment, or from nowhere, which is where most of them end up.

Publishing the standalone file is the whole trick. The catch is which copy of BokehJS the file asks for.

Publish it

from bokeh.plotting import figure, save
from bokeh.resources import INLINE
import requests, os

p = figure(title="Latency p95", x_axis_type="datetime")
p.line(df["ts"], df["p95"])

save(p, filename="plot.html", resources=INLINE, title="Latency p95")

requests.post(
    "https://commareports.com/api/v1/reports",
    headers={"Authorization": f"Bearer {os.environ['COMMA_API_TOKEN']}"},
    json={"title": "Latency p95", "html": open("plot.html").read()},
).raise_for_status()

resources=INLINE is the load-bearing argument. Bokeh's default writes a <script src> pointing at cdn.bokeh.org, and report HTML in Comma runs inside a sandboxed iframe whose script sources are limited to jsdelivr, unpkg, cdnjs and esm.sh. Inlining sidesteps the question entirely and makes the file reproducible three years from now, when that CDN has moved on.

What the URL changes

  • The tools still work. Box zoom, hover, reset, linked brushing across a gridplot — all client-side, all intact. See interactive HTML reports.
  • Someone can argue with the chart in place. Highlight the caption, pin the objection. See commenting on HTML.
  • Reruns become revisions. PATCH the same report id and the URL never changes while the history accumulates.
  • Scheduled refreshes. A routine can re-render the plot nightly against fresh data.

Limits

  • HTML body: 5 MB — inlined BokehJS is 1–2 MB of that. Aggregate wide series before saving.
  • Python callbacks need a Bokeh server and will not fire in a standalone document. Use CustomJS for interactions that must survive publishing.
  • 60 requests/minute per token.

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history.

Publish a plot →

Related