Skip to main content
OpenPlan Labs

planviz

CI docs PyPI License: MIT

The figure library for OpenPlan Labs — grid maps, search animations, plan timelines and benchmark charts, in the Frontier palette, light and dark from the same call.

Planners not included. This draws results; it does not produce them. It knows nothing about any solver's types: a grid is a 2-D array where truthy means blocked, a path is a sequence of (row, col) pairs, and a benchmark series is a mapping. Anything that can produce those can be plotted.

A* on a maze: expanded nodes as filled dots, the frontier as hollow rings, the path as a connected stroke

That figure is the reason this package exists. Every search algorithm has the same three sets — the nodes you expanded, the nodes on the frontier, and the path you returned — so the brand's three colours are that legend, and the three sets differ by shape as well as hue, which is what survives greyscale printing and red/green colour blindness. Drawing it correctly by hand, in four repositories, twice each for light and dark, was the duplication this replaces.

Install

pip install planviz

Two dependencies, both of which a plotting library obviously needs: matplotlib>=3.7 and numpy>=1.24. Python 3.10 or newer.

Not yet on PyPI — until then: pip install git+https://github.com/openplan-labs/planviz.

GIF and MP4 writing needs a little more:

pip install 'planviz[animation]'   # pillow for GIF, a bundled ffmpeg for MP4

Quickstart

import planviz

grid = [[0, 0, 0, 0], [0, 1, 1, 0], [0, 0, 0, 0]]   # truthy = blocked

ax = planviz.draw_search(
    expanded=[(0, 0), (1, 0), (2, 0), (2, 1)],
    frontier=[(0, 1), (2, 2)],
    path=[(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)],
    grid=grid,
    dark=True,
)
planviz.save(ax, "search.png")

Four things hold across the whole API:

  • Importing planviz changes no matplotlib state. The style is applied by planviz.use_style(dark=...), or per-figure inside a style_context that restores rcParams on exit. A solver library can depend on this without repainting its user's notebook.
  • Every figure function takes dark: bool = False and an optional ax=, so light and dark variants come from one call and figures compose into panels.
  • Nothing is saved or shown for you. Functions return the Axes they drew on (or the Figure, for multi-panel figures). planviz.save(...) is the explicit write.
  • The brand ships inside the wheel. planviz/tokens.py and planviz/styles/frontier.mplstyle are generated from openplan-labs/branding and checked for drift in CI, so nothing looks up a repository at runtime and a figure rendered offline matches one rendered on a laptop.

To style figures you draw yourself with the same values:

import matplotlib.pyplot as plt
from planviz import tokens

with planviz.style_context(dark=False) as t:
    fig, ax = plt.subplots()
    ax.plot(xs, ys, color=t.path)          # the solution: the only warm value
    ax.plot(xs, others, color=t.agent(0))  # supporting series: the agent ramp

Gallery

Every image below is generated by examples/gallery.py from synthetic data, in both schemes, and is regenerated in CI. The full gallery with code for each figure is at openplan-labs.github.io/planviz/gallery.

Grids and agents

draw_grid
draw_grid
draw_paths
draw_paths
draw_paths with highlight
draw_paths(highlight=...)
draw_heatmap
draw_heatmap
animate_search animate_paths

animate_search and animate_paths. The frontier moves, the expanded set accumulates, and the path appears once at the end and stays — the accumulated closed list is the cost of the search, so erasing it hides the thing the figure is arguing about. GIFs are capped at 12 fps and 800 px wide, because they are read in a README on a train.

Search progress

search_panels
search_panels
radial_wavefront
radial_wavefront
plan_timeline
plan_timeline
plan_timeline from paths
plan_timeline(timeline_from_paths(...))

Benchmarks

scaling_curve
scaling_curve
success_heatmap
success_heatmap
phase_breakdown
phase_breakdown
crossover_plot
crossover_plot

The API

Style use_style(dark=False), style_context(dark=False), STYLE_PATH
Tokens planviz.tokens — LIGHT, DARK, AGENT_RAMP, Tokens.agent(i), Tokens.sequential()
Grids and agents draw_grid, draw_paths, draw_search, draw_heatmap, animate_paths, animate_search
Search progress search_progress, search_panels, radial_wavefront, plan_timeline, timeline_from_paths, Step
Benchmarks scaling_curve, success_heatmap, phase_breakdown, throughput_curve, crossover_plot
Output save, save_animation, to_jshtml

Full signatures: API reference.

What it does not do

  • No solver adapters. There is no plot_solution(pymapf.Solution). Callers pass arrays and mappings, which is what keeps one library serving four repositories with different problem types.
  • No grouped-bar chart and no parity scatter yet. pymapf's plot_cost_comparison and cuplan's _fig_quality have no home here in 1.0.0; see migration.
  • No 3-D space-time cube. pymapf.viz.plot_spacetime stays where it is.
  • No live views. LiveSolveView and jupyddl's LiveSearchPlot are solver observers, not figures; they belong with the solver they observe.
  • No interactivity, no web renderer. Static matplotlib output, plus GIF and MP4.

Who uses this

Repository What it draws with planviz
pymapf grid maps, multi-agent routes, plan animations, congestion heatmaps, move/wait timelines, scaling charts
cuda-planning the Experiments figures: scaling curves with min–max bands, coverage heatmaps, device phase breakdowns, throughput saturation, crossovers
PythonPDDL --plot search progress, --tree radial wavefront, --plan-plot plan timelines
openplan-bench the cross-repository comparison charts

docs/migration.md maps each of their existing functions onto a planviz call, one line at a time.

Contributing

Bug reports, figures that are wrong, and figures that are missing are all welcome — see CONTRIBUTING.md. The binding constraint is brand/figures.md; the parts of it this library enforces are summarised in design rules.

MIT licensed.

Metadata

Release files for planviz 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for planviz 1.0.0
File Size Uploaded
planviz-1.0.0.tar.gz 58.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for planviz 1.0.0
File Interpreter ABI Platform
planviz-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 100.0 kB

Release files / planviz-1.0.0.tar.gz

Download URL planviz-1.0.0.tar.gz
Size 58.2 kB
Tags Source
SHA-256 checksum
How to use checksums
ca3bc01d718e967fa28af7a641ade85e74388df698083c90b82359bdf7f58074
BLAKE2b-256 checksum
How to use checksums
a8ca625ef4766c0f987fd2788ff9d038446d950595453f4c97a514f956a00e3f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 20, 2026.

Transparency log

Release files / planviz-1.0.0-py3-none-any.whl

Download URL planviz-1.0.0-py3-none-any.whl
Size 41.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ecda40561f02d805cf366724e6c55676145a51a2578dbe5d1c0f12df1bab2056
BLAKE2b-256 checksum
How to use checksums
a781e16008ace705872e6c9c1a4048daf908af067d317cb7d2101e87324fe795
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 20, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page