You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
perf: render shapes via PathCollection of pre-built Paths (avoid per-shape Patch construction) #733
Reframed after profiling (the original to_rgba framing was wrong — it's end-to-end noise).
Root cause
render_shapes (matplotlib) is dominated by per-shape Patch construction, identical across no-color / categorical / continuous color (cProfile, 200k circles, ~23 s):
_build_shape_patches (_geometry.py): ~13 s — one mpatches.Circle/Polygon per shape; each Patch.__init__ resolves default colors via to_rgba (~4×/patch) + recomputes a per-patch transform.
PatchCollection.set_paths: ~6 s — converting all N patches to Paths.
Fix: PathCollection of pre-built Paths
Build Path objects (not Patch objects) and return a matplotlib.collections.PathCollection. These are exactly the Paths PatchCollection.set_paths produces internally, so it's byte-identical (same backend), preserves holes (compound paths) and the existing per-path affine step, keeps all color/alpha/outline logic, is one code path, and needs no signature change.
Measured (200k circles, build+draw): ~2.6× faster, ~5.8× less memory (11.7 s/149 MB vs 30.1 s/867 MB), color-mode-independent.
Rejected:EllipseCollection/PolyCollection — incompatible with the coordinate-system affine applied per-path (EllipseCollection has one shared read-only path), PolyCollection can't represent holes, and EllipseCollection tessellates circles coarsely. Not byte-identical.
changed the title [-]perf: shapes matplotlib fill expands the compact categorical colour to an (N,4) RGBA buffer[/-][+]perf: render shapes via PathCollection of pre-built Paths (avoid per-shape Patch construction)[/+]on Jun 21, 2026
Activity
[-]perf: shapes matplotlib fill expands the compact categorical colour to an (N,4) RGBA buffer[/-][+]perf: render shapes via PathCollection of pre-built Paths (avoid per-shape Patch construction)[/+]