Harmonic Sequence Viz#

biotuner/harmonic_sequence_viz.py#

Visualization utilities for the harmonic_sequence module.

Module type: Functions

Every function accepts an optional ax argument so panels can be embedded in larger figure layouts. When ax is None a new figure is created.

All multi-panel overview / comparison helpers save their output to figdir (default "hs_figures").

Quick reference#

Per-model panels:

plot_histogram_heatmap – cents distribution heatmap over time plot_wasserstein_flux – consecutive W1 distances plot_wasserstein_matrix – symmetric pairwise W1 matrix plot_markov_matrix – annotated Markov transition matrix plot_latent_trajectory – 2-D PCA path coloured by time plot_dmd_spectrum – eigenvalues on the complex plane plot_topology_barcode – persistence barcode (H0, H1) plot_grammar_interval_heatmap – JI interval presence timeline

Composite figures:

plot_scenario_overview – 6-panel overview for one scenario plot_comparison_flux – Wasserstein flux for all scenarios plot_comparison_latent – latent trajectories for all scenarios plot_comparison_summary – 4-panel bar-chart summary across scenarios

plot_histogram_heatmap(analyzer, ax: Axes | None = None, title: str = 'Harmonic Interval Distribution', cmap: str = 'magma', vmax: float | None = None, percentile_clip: float = 98.0, gamma: float = 0.5) Axes[source]#

Heatmap of normalised cents histograms.

X-axis = time step, Y-axis = cents [0, 1200]. Colour encodes density (brighter = more energy).

Parameters:
  • analyzer (HarmonicSequenceAnalyzer)

  • ax (Axes, optional)

  • title (str)

  • cmap (str, default 'magma')

  • vmax (float, optional) – Explicit colour-scale ceiling. When None (default), vmax is set to the percentile_clip-th percentile of non-zero histogram values to avoid a few bright peaks washing out the rest.

  • percentile_clip (float, default 98.0) – Percentile (of non-zero values) used to compute vmax automatically.

  • gamma (float, default 0.5) – Power-norm exponent applied before mapping to colours. Values < 1 brighten low-density regions (square-root at 0.5). Set to 1.0 to disable.

plot_wasserstein_flux(analyzer, ax: Axes | None = None, title: str = 'Wasserstein Flux', color: str = '#3498db', fill: bool = True) Axes[source]#

Line plot of consecutive W₁ distances (harmonic velocity).

Parameters:
  • analyzer (HarmonicSequenceAnalyzer)

  • ax (Axes, optional)

  • title (str)

  • color (str)

  • fill (bool shade area under the flux curve)

plot_wasserstein_matrix(analyzer, ax: Axes | None = None, title: str = 'Pairwise W₁ Distance', cmap: str = 'YlOrRd') Axes[source]#

Symmetric pairwise Wasserstein distance matrix.

Parameters:
  • analyzer (HarmonicSequenceAnalyzer)

  • ax (Axes, optional)

  • title (str)

  • cmap (str)

plot_markov_matrix(analyzer, ax: Axes | None = None, title: str = 'Markov Transition Matrix', cmap: str = 'Blues', annotate: bool = True) Axes[source]#

Annotated heatmap of the Markov transition probability matrix.

Parameters:
  • analyzer (HarmonicSequenceAnalyzer)

  • ax (Axes, optional)

  • title (str)

  • cmap (str)

  • annotate (bool write probability values inside each cell)

plot_latent_trajectory(analyzer, dims: Tuple[int, int] = (0, 1), ax: Axes | None = None, title: str = 'Latent Harmonic Trajectory', cmap: str = 'plasma', arrow_every: int = 4) Axes[source]#

Scatter of latent PCA coordinates, coloured by time step.

Arrows are drawn every arrow_every steps to indicate direction of travel.

Parameters:
  • analyzer (HarmonicSequenceAnalyzer)

  • dims ((int, int) which PC pair to plot)

  • ax (Axes, optional)

  • title (str)

  • cmap (str)

  • arrow_every (int)

plot_dmd_spectrum(analyzer, ax: Axes | None = None, title: str = 'DMD Eigenvalue Spectrum', annotate_osc: bool = True) Axes[source]#

Eigenvalues plotted on the complex plane with the unit circle.

Colour encodes |λ| (green = near unit circle = sustained oscillation).

Parameters:
  • analyzer (HarmonicSequenceAnalyzer)

  • ax (Axes, optional)

  • title (str)

  • annotate_osc (bool label oscillatory modes with their period)

plot_topology_barcode(analyzer, ax: Axes | None = None, title: str = 'Persistence Barcode', max_bars: int = 20, dim_colors: Tuple[str, str] = ('#3498db', '#e74c3c')) Axes[source]#

Horizontal persistence barcode for H0 (and H1 if available).

Parameters:
  • analyzer (HarmonicSequenceAnalyzer)

  • ax (Axes, optional)

  • title (str)

  • max_bars (int maximum bars per homological dimension)

  • dim_colors (tuple of 2 str colours for H0 and H1)

plot_grammar_interval_heatmap(analyzer, ax: Axes | None = None, title: str = 'JI Interval Presence over Time', top_n: int = 15, cmap: str = 'Blues') Axes[source]#

Binary heatmap of JI interval presence across time.

The top top_n most frequently occurring named intervals are shown.

Parameters:
  • analyzer (HarmonicSequenceAnalyzer)

  • ax (Axes, optional)

  • title (str)

  • top_n (int)

  • cmap (str)

plot_scenario_overview(analyzer, scenario_name: str, scenario_color: str = '#3498db', figdir: str = 'hs_figures', save: bool = True) Figure[source]#

Six-panel overview figure for one scenario.

Panels (3 rows × 3 cols, row 0 spans all columns):

[0, :] cents histogram heatmap (full width) [1, 0] Wasserstein flux [1, 1] Wasserstein distance matrix [1, 2] Markov transition matrix [2, 0] latent PCA trajectory [2, 1] DMD eigenvalue spectrum [2, 2] (empty)

Parameters:
  • analyzer (HarmonicSequenceAnalyzer)

  • scenario_name (str used in the title and filename)

  • scenario_color (str accent colour for flux / latent plots)

  • figdir (str output directory)

  • save (bool write the figure to *figdir*)

Returns:

fig (matplotlib Figure)

plot_comparison_flux(analyzers: List, names: List[str], colors: List[str] | None = None, figdir: str = 'hs_figures', save: bool = True) Figure[source]#

Subplot grid showing Wasserstein flux for each scenario.

Parameters:
  • analyzers (list of HarmonicSequenceAnalyzer)

  • names (list of str scenario labels)

  • colors (list of str, optional)

  • figdir (str)

  • save (bool)

Returns:

fig (Figure)

plot_comparison_latent(analyzers: List, names: List[str], colors: List[str] | None = None, figdir: str = 'hs_figures', save: bool = True) Figure[source]#

Latent-space (PC1 vs PC2) trajectories for all scenarios.

Parameters:
  • analyzers (list of HarmonicSequenceAnalyzer)

  • names (list of str)

  • colors (list of str, optional)

  • figdir (str)

  • save (bool)

Returns:

fig (Figure)

plot_comparison_summary(analyzers: List, names: List[str], colors: List[str] | None = None, figdir: str = 'hs_figures', save: bool = True) Figure[source]#

Four-panel summary bar charts comparing all scenarios.

Panels:

TL Markov transition entropy (bits) TR Mean Wasserstein flux BL PCA explained variance (first 2 PCs) BR Grammar transition entropy (bits)

Parameters:
  • analyzers (list of HarmonicSequenceAnalyzer)

  • names (list of str)

  • colors (list of str, optional)

  • figdir (str)

  • save (bool)

Returns:

fig (Figure)

plot_tda_grammar_grid(analyzers: List, names: List[str], figdir: str = 'hs_figures', save: bool = True) Figure[source]#

Grid of persistence barcodes and grammar interval heatmaps.

Layout: one row per scenario, two columns (barcode | interval heatmap).

Parameters:
  • analyzers (list of HarmonicSequenceAnalyzer)

  • names (list of str)

  • figdir (str)

  • save (bool)

Returns:

fig (Figure)