Plotting#
biotuner.harmonic_geometry.plotting#
Visualisation for GeometryData objects.
This module is the single home for matplotlib-based rendering of every
geom_type produced by the rest of biotuner.harmonic_geometry
(curve/polygon/graph/tree/field/mesh/point-cloud, in 2-D and 3-D), plus
the higher-level helpers used by the report generator scripts (galleries,
sweep strips, rotation gifs, GA fitness curves, grid-relaxation animations).
Matplotlib is imported lazily inside each function so that simply importing
biotuner.harmonic_geometry does not pull in the matplotlib stack.
Sections#
Style helpers — palette, axis cleanup, figure save
2-D primitive renderers — curve/polygon/graph/field/cloud/tree/rectangles
3-D primitive renderers — mesh/cloud/tree, plus 3-D axis helpers
Dispatcher —
plot_geometry()Layout helpers — galleries and parameter sweeps
Animation helpers — rotation, sequence, grid relax, evolution
Resonance helpers — coupling matrices, GA curves, attractor graphs
Public API is exported through biotuner.harmonic_geometry.__init__ so
external code can simply from biotuner.harmonic_geometry import plotting
or import individual functions.
- axis_clean(ax, equal: bool = True, grid: bool = False, spine_color: str = '#cccccc', spine_lw: float = 0.5) None[source]#
Strip ticks, harmonise spines, optionally enforce equal aspect / grid.
- title_ax(ax, text: str, sub: str = '', fontsize: int = 8) None[source]#
Two-line axis title; the second line is rendered smaller and dimmer.
- make_axis_3d(fig, pos, title: str = '', elev: int = 25, azim: int = 45)[source]#
Create a 3-D matplotlib axis with cleaned spines and equal aspect.
- save_figure(fig, path: str | Path, dpi: int = 150, close: bool = True) Path[source]#
Save
figtopath(creating parent dirs) and optionally close it.
- draw_curve_2d(geom: GeometryData, ax, color: str = '#1f3b73', lw: float = 0.9, marker: str | None = None) None[source]#
Polyline in 2-D.
- draw_polygon(geom: GeometryData, ax, color: str = '#a23e2c', lw: float = 1.4, fill: bool = False, alpha: float = 0.08, marker: str | None = 'o', ms: float = 4) None[source]#
Closed polygon (auto-closes by appending the first vertex).
- draw_polygon_set(geom: GeometryData, ax, palette: Sequence[str] | None = None, lw: float = 1.4, ms: float = 3) None[source]#
List/sequence of polygons (geom.coordinates is iterable of (k, 2) arrays).
- draw_graph_2d(geom: GeometryData, ax, edge_color: str = '#1f3b73', edge_lw: float = 0.4, edge_alpha: float = 0.55, node_color: str = '#a23e2c', node_size: float = 4, use_weights: bool = False) None[source]#
Edges as a LineCollection plus node scatter.
- draw_hyperbolic_graph(geom: GeometryData, ax, color_by: str = 'harmonicity', cmap: str = 'plasma', highlight_mask: ndarray | None = None, highlight_color: str = '#a23e2c', show_disk: bool = True) Any[source]#
Stern-Brocot hyperbolic-disk layout. Returns the scatter (for colorbar).
- draw_point_cloud_2d(geom: GeometryData, ax, color: str = '#a23e2c', edge_color: str = '#1f3b73', size: float = 30, use_weights: bool = True, ref_circle: bool = False) None[source]#
2-D scatter; sizes scaled by geom.weights when present.
- draw_field_2d(geom: GeometryData, ax, cmap: str = 'RdBu_r', show_nodal: bool = True, signed: bool = True, vmin: float | None = None, vmax: float | None = None) Any[source]#
Pcolormesh of a 2-D scalar field stored in geom.coordinates.
For signed fields (e.g. Chladni) draws a zero-level contour. Returns the QuadMesh object (so callers can attach a colorbar).
- draw_image(geom: GeometryData, ax, cmap: str = 'inferno', origin: str = 'lower', extent: Tuple[float, float, float, float] | None = None, vmin: float = 0.0, vmax: float = 1.0) Any[source]#
Imshow renderer for fields stored as a (H, W) array (Julia, Cantor, …).
- draw_tree_2d(geom: GeometryData, ax, color: str = '#1f3b73', lw: float = 0.5, alpha: float = 0.75) None[source]#
L-system / fractal tree edges drawn as a LineCollection.
- draw_rectangles(geom: GeometryData, ax, cmap: str = 'tab10', edge_color: str = 'white', edge_lw: float = 0.8) None[source]#
Continued-fraction rectangle tilings — a sequence of (4, 2) polygons.
- draw_mesh_3d(ax, geom: GeometryData, color: str = '#1f3b73', alpha: float = 0.75, lw: float = 0.2, edge_color: str = 'white') None[source]#
3-D triangle mesh via Poly3DCollection.
- draw_tree_3d(ax, geom: GeometryData, color: str = '#1f3b73', lw: float = 0.5, alpha: float = 0.7) None[source]#
3-D L-system tree edges via Line3DCollection.
- draw_point_cloud_3d(ax, geom: GeometryData, color: str = '#a23e2c', size: float = 2, alpha: float = 0.6) None[source]#
3-D scatter.
- draw_curve_3d(ax, geom: GeometryData, color: str = '#1f3b73', lw: float = 0.6) None[source]#
3-D polyline.
- plot_geometry(geom: GeometryData, ax=None, **kwargs)[source]#
Auto-route a
GeometryDatato the matching renderer.- Parameters:
geom (GeometryData)
ax (matplotlib axis, optional) – If
None, a new figure is created with the appropriate projection.**kwargs – Forwarded to the underlying drawer.
- Returns:
(fig, ax) (tuple)
- gallery(geometries: Sequence[GeometryData], titles: Sequence[str] | None = None, n_cols: int = 3, fig_width: float = 6.5, row_height: float | None = None, color: str | Sequence[str] | None = None, suptitle: str | None = None, draw_kwargs: Dict[str, Any] | None = None, renderer: Callable | None = None)[source]#
Render an N × n_cols grid of geometries via
plot_geometry().Use
rendererto force a specific drawer (otherwise dispatched per-geom).colormay be a single string (applied to all) or a list. Returns(fig, axes).
- sweep_strip(geometries: Sequence[GeometryData], labels: Sequence[str] | None = None, fig_width: float = 6.5, row_height: float | None = None, color: str = '#1f3b73', suptitle: str | None = None, draw_kwargs: Dict[str, Any] | None = None, renderer: Callable | None = None)[source]#
1×N strip — convenience wrapper over
gallery()with n_cols=N.
- rotation_strip(geom: GeometryData, n_strip: int = 6, fig_width: float = 6.5, elev: float = 20.0, color: str = '#1f3b73', draw_kwargs: Dict[str, Any] | None = None, renderer: Callable | None = None, suptitle: str | None = None)[source]#
1×N strip of the same 3-D geometry at evenly spaced azimuths.
Returns
(fig, axes). Useful for showing a tube/knot/mesh from several viewing angles in a single static figure.
- animate_rotation(geom: GeometryData, out_path: str | Path, n_frames: int = 36, fps: int = 12, elev: float = 20.0, fig_size: Tuple[float, float] = (3.5, 3.5), dpi: int = 100, color: str = '#1f3b73', draw_kwargs: Dict[str, Any] | None = None, renderer: Callable | None = None) Path[source]#
Save a rotating GIF of a 3-D
GeometryData(mesh / tree / cloud).Frames sweep azimuth from 0° to (n_frames−1) × (360 / n_frames).
rendererdefaults toplot_geometry()’s 3-D dispatch.
- animate_geometry_sequence(geoms: Sequence[GeometryData], out_path: str | Path, fps: int = 8, fig_size: Tuple[float, float] = (4.5, 4.5), dpi: int = 100, color: str = '#1f3b73', draw_kwargs: Dict[str, Any] | None = None, elev: float = 25.0, azim: float = 35.0) Path[source]#
Save a GIF cycling through a list of geometries (2-D or 3-D).
- plot_metric_radar(rows, labels: Sequence[str] | None = None, metrics: Sequence[str] | None = None, ax=None, colors: Sequence[str] | None = None, fill_alpha: float = 0.2, line_lw: float = 1.4, title: str | None = None)[source]#
Radar chart of normalised metrics for one or several rows.
- Parameters:
rows (dict or list of dicts) – Either a single
{metric: value}dict (one polygon) or a list of such dicts (multi-overlay). Values are auto-normalised to [0, 1] viabiotuner.harmonic_geometry.metrics.normalize_metrics().labels (sequence of str, optional) – One label per row. Defaults to
row_0, row_1, ….metrics (sequence of str, optional) – Subset of metric keys to include. Defaults to the keys of the first row (with
n_componentsexcluded — it’s a count, not a metric).ax (polar matplotlib axis, optional)
colors (sequence of str, optional)
fill_alpha, line_lw (floats)
title (str, optional)
- Returns:
(fig, ax) (tuple)
- plot_metric_trajectory(metrics_dict_or_seq, generator: Any | None = None, generator_kwargs: Dict[str, Any] | None = None, metrics: Sequence[str] | None = None, times: ndarray | None = None, ax=None, normalize: bool = False, colors: Sequence[str] | None = None, title: str | None = None)[source]#
Line plot of geometry-metric trajectories over time.
Two ways to pass data:
Pre-computed:
metrics_dict_or_seqis a dict{name: 1-D ndarray of length T}— typically the output ofsequence_metrics().generatorshould beNone.From a HarmonicSequence: pass the sequence as the first argument and supply
generator(e.g.harmonic_knot). The function computessequence_metrics(seq, generator, **kwargs)()internally.
- Parameters:
metrics_dict_or_seq (dict[str, ndarray] or HarmonicSequence)
generator (callable, optional) – Required when the first argument is a
HarmonicSequence.generator_kwargs (dict, optional) – Forwarded to
generatorfor every frame.metrics (sequence of str, optional) – Subset of metric trajectories to plot. Defaults to all keys.
times (ndarray, optional) – Explicit time axis. Inferred from the sequence if available.
ax (matplotlib axis, optional)
normalize (bool, default False) – Per-metric min-max scaling to [0, 1].
- Returns:
(fig, ax) (tuple)