A plotting library using python, javascript and anywidget for performant in browser plotting.
Project description
anyplotlib
anyplotlib is a fast, interactive plotting library for Jupyter, built on
anywidget and a pure-JavaScript canvas renderer.
It follows matplotlib's object-oriented API — create a Figure, call methods
on Axes — so switching is often a one-line change:
import anyplotlib as apl
fig, ax = apl.subplots(1, 1) # same shape as plt.subplots(1, 1)
ax.imshow(data) # pan, zoom, and inspect — live
fig # display in a Jupyter cell
If you have used matplotlib's OO interface, you already know most of anyplotlib. What you gain is interactivity that stays fast on large data — without a kernel round-trip per frame.
Why another plotting library?
Matplotlib is a superb tool for publication-quality static figures, but its
interactive notebook story (ipympl) re-renders the whole figure on the
Python side for every frame. anyplotlib makes the opposite trade-off:
- All rendering happens in the browser. Python serialises compact state (raw image bytes, base64-encoded float arrays) once; pan/zoom/drag never touch the kernel.
- Each image, line collection, or marker group is a single canvas object, so blitting works and drag interactions run at full frame rate.
- The scope is deliberately limited. The OO API only (no
plt.plot()global state), a curated set of plot types and marker styles, and raster canvas output rather than vector graphics. For print-quality SVG/PDF figures, matplotlib remains the right tool.
Features
- Plot types —
plot(1-D lines with markers, linestyles, legends, log y),imshow(2-D images with colormaps, colorbars, scale bars, overlay masks),pcolormesh(non-uniform 2-D meshes),bar(grouped, horizontal, log, value labels), and 3-Dplot_surface/scatter3d/plot3d. - Layouts —
subplots, matplotlib-compatibleGridSpecindexing (slices, spans, negative indices),width_ratios/height_ratios,sharex/shareylinked pan-zoom, and floating inset axes with minimize/maximize. - Markers — static overlays (points, circles, ellipses, rectangles,
polygons, arrows, line segments, text, h/v lines) with matplotlib-style
kwargs and live
.set()updates. - Widgets — draggable overlays (
RectangleWidget,CircleWidget,AnnularWidget,CrosshairWidget,PolygonWidget,VLineWidget,HLineWidget,RangeWidget, …) that report positions back to Python. - Events — a two-tier callback system:
pointer_movefires every drag frame for cheap updates;pointer_settled/pointer_upfire once for expensive recomputation. Pluskey_down,wheel,double_click, and per-line scoped handlers. - Interactive docs — the bundled
anyplotlib.sphinx_anywidgetextension makes any anywidget figure live in Sphinx Gallery pages via Pyodide — no kernel or server needed. - Embeddable anywhere — figures don't require Jupyter. Export
self-contained HTML (
fig.save_html("plot.html")), mount the renderer directly in an Electron app or web page via the JSmount()API, or run a live Python backend over any transport withanyplotlib.embed.FigureBridge(full callback support). See the embedding guide in the docs.
import numpy as np
import anyplotlib as apl
fig, (ax_img, ax_spec) = apl.subplots(1, 2, figsize=(900, 400))
img = ax_img.imshow(stack.mean(axis=2), cmap="viridis")
spec = ax_spec.plot(stack[64, 64], units="eV")
cross = img.add_widget("crosshair", cx=64, cy=64)
@cross.add_event_handler("pointer_move") # every drag frame — keep it cheap
def update(event):
spec.set_data(stack[int(cross.cy), int(cross.cx)])
Installation
pip install anyplotlib
Works anywhere anywidget does: JupyterLab, Jupyter Notebook, VS Code,
PyCharm, Google Colab, and marimo. Dependencies are intentionally light:
anywidget, numpy, traitlets, and colorcet (no matplotlib required).
Documentation
Full docs, a live example gallery (interactive in the browser — no install), and the event-system guide are at cssfrancis.github.io/anyplotlib.
Development
git clone https://github.com/CSSFrancis/anyplotlib
cd anyplotlib
uv sync # install with dev dependencies
uv run playwright install chromium # browsers for rendering tests
uv run pytest # full suite (unit + Playwright + visual)
make html # build the docs locally
The architecture is a single anywidget.AnyWidget (Figure) that owns all
traitlets; plot objects are plain Python classes that serialise their state
dicts to per-panel traits, and figure_esm.js renders them. See
AGENTS.md for the codebase guide and
anyplotlib/FIGURE_ESM.md for a map of the JS
renderer.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file anyplotlib-0.1.0.tar.gz.
File metadata
- Download URL: anyplotlib-0.1.0.tar.gz
- Upload date:
- Size: 1.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
31a5084bd504c291022012e4a4f2f6494f44fd5f4067f7b80807558a99775050
|
|
| MD5 |
a73eb598dd2518d22639597c70d2edeb
|
|
| BLAKE2b-256 |
c26fa1c15d29891e42e22bef95b8c8fe772ca0c66094e45973e4fabd0e5aafe6
|
Provenance
The following attestation bundles were made for anyplotlib-0.1.0.tar.gz:
Publisher:
release.yml on CSSFrancis/anyplotlib
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
anyplotlib-0.1.0.tar.gz -
Subject digest:
31a5084bd504c291022012e4a4f2f6494f44fd5f4067f7b80807558a99775050 - Sigstore transparency entry: 2013115491
- Sigstore integration time:
-
Permalink:
CSSFrancis/anyplotlib@2186b0b38ff35c14511c7de63de84683cbf09349 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/CSSFrancis
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2186b0b38ff35c14511c7de63de84683cbf09349 -
Trigger Event:
push
-
Statement type:
File details
Details for the file anyplotlib-0.1.0-py3-none-any.whl.
File metadata
- Download URL: anyplotlib-0.1.0-py3-none-any.whl
- Upload date:
- Size: 194.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a1192e60229b1c0505ee60190c9a130acb54a86206ce46cde2632a430ac8e050
|
|
| MD5 |
1a32c45df2f300bfb891a01dcd8cf591
|
|
| BLAKE2b-256 |
3c93351475bbd314e6545b30cfc7d4e26421e6e8f0f142df35786d43bd437c2a
|
Provenance
The following attestation bundles were made for anyplotlib-0.1.0-py3-none-any.whl:
Publisher:
release.yml on CSSFrancis/anyplotlib
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
anyplotlib-0.1.0-py3-none-any.whl -
Subject digest:
a1192e60229b1c0505ee60190c9a130acb54a86206ce46cde2632a430ac8e050 - Sigstore transparency entry: 2013115553
- Sigstore integration time:
-
Permalink:
CSSFrancis/anyplotlib@2186b0b38ff35c14511c7de63de84683cbf09349 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/CSSFrancis
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2186b0b38ff35c14511c7de63de84683cbf09349 -
Trigger Event:
push
-
Statement type: