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.tokensLIGHT, 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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

planviz-1.0.0.tar.gz (58.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

planviz-1.0.0-py3-none-any.whl (41.8 kB view details)

Uploaded Python 3

File details

Details for the file planviz-1.0.0.tar.gz.

File metadata

  • Download URL: planviz-1.0.0.tar.gz
  • Upload date:
  • Size: 58.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for planviz-1.0.0.tar.gz
Algorithm Hash digest
SHA256 ca3bc01d718e967fa28af7a641ade85e74388df698083c90b82359bdf7f58074
MD5 cf2212a3ff89f0ed4b4e769aa83d8804
BLAKE2b-256 a8ca625ef4766c0f987fd2788ff9d038446d950595453f4c97a514f956a00e3f

See more details on using hashes here.

Provenance

The following attestation bundles were made for planviz-1.0.0.tar.gz:

Publisher: release.yml on openplan-labs/planviz

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file planviz-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: planviz-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 41.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for planviz-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ecda40561f02d805cf366724e6c55676145a51a2578dbe5d1c0f12df1bab2056
MD5 ba71b20bcb05903a2c95f7ea2437eb46
BLAKE2b-256 a781e16008ace705872e6c9c1a4048daf908af067d317cb7d2101e87324fe795

See more details on using hashes here.

Provenance

The following attestation bundles were made for planviz-1.0.0-py3-none-any.whl:

Publisher: release.yml on openplan-labs/planviz

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page