Plot Utils#

Biotuner Plotting Utilities#

Module type: Functions

This module provides unified plotting functions for all biotuner visualizations, ensuring consistent styling across different peak extraction methods and analyses.

Author: Biotuner Team

plot_psd_peaks(freqs: ndarray, psd: ndarray, peaks: ndarray, xmin: float = 1, xmax: float = 60, title: str | None = None, method: str | None = None, figsize: Tuple[float, float] | None = None, color: str | None = None, peak_color: str | None = None, show_bands: bool = False, bands: Dict[str, List[float]] | None = None, ax: Axes | None = None, **kwargs) Tuple[Figure, Axes][source]#

Universal function to plot PSD with peak markers.

Parameters:
  • freqs (np.ndarray) – Frequency vector

  • psd (np.ndarray) – Power spectral density values

  • peaks (np.ndarray) – Peak frequencies to mark

  • xmin, xmax (float) – X-axis limits in Hz

  • title (str, optional) – Custom plot title

  • method (str, optional) – Peak extraction method name (used in default title)

  • figsize (tuple, optional) – Figure size (width, height)

  • color (str, optional) – Line color for PSD. Default: BIOTUNER_COLORS[‘primary’]

  • peak_color (str, optional) – Color for peak markers. Default: BIOTUNER_COLORS[‘accent’]

  • show_bands (bool, default=False) – Whether to show frequency band overlays

  • bands (dict, optional) – Custom frequency bands. Default: standard EEG bands

  • ax (plt.Axes, optional) – Existing axes to plot on

  • **kwargs – Additional arguments passed to plt.plot()

Returns:

  • fig (plt.Figure) – Matplotlib figure object

  • ax (plt.Axes) – Matplotlib axes object

Examples

>>> fig, ax = plot_psd_peaks(freqs, psd, peaks, xmin=1, xmax=60,
...                          method='EMD', show_bands=True)
>>> plt.show()
plot_emd_peaks(freqs_all: List[ndarray] | ndarray | None = None, psd_all: List[ndarray] | ndarray | None = None, peaks: ndarray | None = None, raw_data: ndarray | None = None, sf: float = 1000, xmin: float = 1, xmax: float = 60, figsize: Tuple[float, float] | None = None, show_bands: bool = True, bands: Dict[str, List[float]] | None = None, compare_raw: bool = True, colors: List[str] | None = None, ax: Axes | None = None, IMFs: List[ndarray] | None = None, nperseg: int | None = None, precision: float = 0.5, smooth: int = 1, use_db: bool = True, fill_imfs: bool = False, log_scale: bool = False, **kwargs) Tuple[Figure, Axes][source]#

Plot EMD decomposition with peaks.

Parameters:
  • freqs_all (list of np.ndarray, optional) – Frequency vectors for each IMF. If None, will compute from IMFs.

  • psd_all (list of np.ndarray, optional) – PSD values for each IMF. If None, will compute from IMFs.

  • peaks (np.ndarray) – Detected peak frequencies

  • raw_data (np.ndarray, optional) – Raw signal for comparison

  • sf (float, default=1000) – Sampling frequency in Hz

  • xmin, xmax (float) – Frequency limits

  • figsize (tuple, optional) – Figure size

  • show_bands (bool, default=True) – Show frequency band overlays

  • bands (dict, optional) – Custom frequency bands

  • compare_raw (bool, default=True) – Overlay raw signal PSD

  • colors (list, optional) – Custom colors for IMFs

  • ax (plt.Axes, optional) – Existing axes

  • IMFs (list of np.ndarray, optional) – List of intrinsic mode functions. If provided, will compute PSD internally.

  • nperseg (int, optional) – Length of each segment for Welch’s method. If None, calculated from precision.

  • precision (float, default=0.5) – Frequency bin size in Hz. Used to calculate nperseg if not provided.

  • smooth (int, default=1) – Smoothing factor for nperseg calculation.

  • use_db (bool, default=True) – Convert PSD to decibels (10*log10). Matches other methods.

  • fill_imfs (bool, default=False) – Fill area under IMF curves. Disabled by default for cleaner visualization.

  • log_scale (bool, default=False) – Use logarithmic scales for both axes. Set to True for traditional EMD visualization, False for linear scales to match other methods (FOOOF, fixed, etc.).

  • **kwargs – Additional plot parameters

Returns:

  • fig (plt.Figure) – Matplotlib figure

  • ax (plt.Axes) – Matplotlib axes

Examples

>>> # Automatic PSD computation from IMFs
>>> fig, ax = plot_emd_peaks(peaks=peaks, IMFs=bt.IMFs, sf=1000)
>>>
>>> # Manual PSD specification
>>> fig, ax = plot_emd_peaks(freqs_all, psd_all, peaks,
...                          raw_data=data, sf=1000)
>>> plt.show()
plot_harmonic_peaks(freqs: ndarray, psd: ndarray, harm_peaks_fit: List[Tuple], xmin: float = 1, xmax: float = 60, n_peaks: int = 5, figsize: Tuple[float, float] | None = None, color: str | None = None, show_bands: bool = False, ax: Axes | None = None, selected_peaks: ndarray | None = None, **kwargs) Tuple[Figure, Axes][source]#

Plot harmonic recurrence with fitted harmonics using new unified style.

Parameters:
  • freqs (np.ndarray) – Frequency vector

  • psd (np.ndarray) – Power spectral density

  • harm_peaks_fit (list of tuples) – Harmonic fit information: [(peak, harmonic_positions, harmonic_freqs), …]

  • xmin, xmax (float) – Frequency limits

  • n_peaks (int, default=5) – Number of fundamental peaks to display

  • figsize (tuple, optional) – Figure size

  • color (str, optional) – PSD line color

  • show_bands (bool, default=False) – Whether to show frequency bands

  • ax (plt.Axes, optional) – Existing axes

  • selected_peaks (np.ndarray, optional) – The actual selected peaks from harmonic_recurrence algorithm (bt.peaks). If provided, only these peaks from harm_peaks_fit will be plotted.

  • **kwargs – Additional parameters

Returns:

  • fig (plt.Figure) – Matplotlib figure

  • ax (plt.Axes) – Matplotlib axes

Examples

>>> fig, ax = plot_harmonic_peaks(freqs, psd, harm_peaks_fit,
...                                xmin=1, xmax=60, n_peaks=5,
...                                selected_peaks=bt.peaks)
>>> plt.show()
plot_peaks(method: str | None = None, freqs: List[ndarray] | ndarray | None = None, psd: List[ndarray] | ndarray | None = None, peaks: ndarray | None = None, xmin: float = 1, xmax: float = 60, show_bands: bool = False, show_matrix: bool = False, matrix_metric: str = 'harmsim', bt_object=None, **kwargs) Tuple[Figure, Axes | ndarray]#

Universal summary plotting function for peak extraction results.

Plots a comprehensive summary with spectrum, amplitude distribution, and optionally harmonicity matrix. For individual plots, use plot_peaks_spectrum(), plot_peaks_amplitude(), or plot_peaks_matrix().

Automatically dispatches to the appropriate plotting function based on method. Can accept a biotuner object directly for simplified usage.

Parameters:
  • method (str, optional) – Peak extraction method: ‘EMD’, ‘EEMD’, ‘CEEMDAN’, ‘FOOOF’, ‘harmonic_recurrence’, ‘EIMC’, ‘cepstrum’, ‘bicoherence’, ‘PAC’, ‘fixed’, ‘adapt’, ‘HH1D_max’, etc. If bt_object is provided, method will be extracted from it.

  • freqs (np.ndarray or list of np.ndarray, optional) – Frequency vector(s). Not required if bt_object or IMFs are provided.

  • psd (np.ndarray or list of np.ndarray, optional) – PSD data. Not required if bt_object or IMFs are provided.

  • peaks (np.ndarray, optional) – Detected peak frequencies. Extracted from bt_object if not provided.

  • xmin, xmax (float) – Frequency range

  • show_bands (bool, default=False) – Whether to overlay frequency bands

  • show_matrix (bool, default=False) – Whether to show peak ratios harmonicity matrix in a second panel

  • matrix_metric (str, default=’harmsim’) – Metric to use for matrix computation: - ‘harmsim’: Harmonic similarity (higher = more harmonic) - ‘cons’: Consonance (higher = more consonant) - ‘tenney’: Tenney height (higher = more dissonant) - ‘denom’: Denominator complexity (higher = more dissonant) - ‘subharm_tension’: Subharmonic tension

  • bt_object (compute_biotuner, optional) – Biotuner object. If provided, attributes will be extracted automatically.

  • **kwargs – Method-specific parameters

Returns:

  • fig (plt.Figure) – Matplotlib figure

  • ax (plt.Axes or np.ndarray) – Matplotlib axes (single or array if show_matrix=True)

Examples

>>> # Using biotuner object (recommended)
>>> bt = compute_biotuner(sf=1000, peaks_function='FOOOF')
>>> bt.peaks_extraction(data=signal, min_freq=1, max_freq=50)
>>> fig, ax = plot_peaks(bt_object=bt, show_bands=True, show_matrix=True)
>>>
>>> # Manual mode (backward compatible)
>>> fig, ax = plot_peaks('FOOOF', freqs, psd, peaks, show_bands=True)
>>>
>>> # With harmonicity matrix
>>> fig, axes = plot_peaks(bt_object=bt, show_matrix=True, matrix_metric='harmsim')
>>> plt.show()
plot_tuning_dissonance(ratio_vec: ndarray, diss_curve: ndarray, diss_scale: List[float] | None = None, intervals: List[Tuple[int, int]] | None = None, n_tet_grid: int | None = None, max_ratio: float = 2, show_intervals: bool = True, show_tet_grid: bool = False, denom: int = 1000, figsize: Tuple[float, float] | None = None, ax: Axes | None = None, **kwargs) Tuple[Figure, Axes][source]#

Plot dissonance curve with unified biotuner styling.

Parameters:
  • ratio_vec (np.ndarray) – Frequency ratios for x-axis

  • diss_curve (np.ndarray) – Dissonance values

  • diss_scale (list of float, optional) – Scale derived from dissonance minima

  • intervals (list of tuples, optional) – Interval ratios as (numerator, denominator) pairs. If None and diss_scale is provided, will compute from ratios.

  • n_tet_grid (int, optional) – N-TET reference grid (e.g., 12 for 12-TET)

  • max_ratio (float, default=2) – Maximum ratio to display

  • show_intervals (bool, default=True) – Show vertical lines at scale intervals

  • show_tet_grid (bool, default=False) – Show N-TET reference grid

  • denom (int, default=1000) – Denominator limit for fraction conversion

  • figsize (tuple, optional) – Figure size

  • ax (plt.Axes, optional) – Existing axes

Returns:

fig, ax (matplotlib figure and axes)

plot_tuning_entropy(ratio_vec: ndarray, entropy_curve: ndarray, entropy_scale: List[float] | None = None, max_ratio: float = 2, show_minima: bool = True, figsize: Tuple[float, float] | None = None, ax: Axes | None = None, **kwargs) Tuple[Figure, Axes][source]#

Plot harmonic entropy curve with unified biotuner styling.

Parameters:
  • ratio_vec (np.ndarray) – Frequency ratios for x-axis

  • entropy_curve (np.ndarray) – Harmonic entropy values

  • entropy_scale (list of float, optional) – Scale derived from entropy minima

  • max_ratio (float, default=2) – Maximum ratio to display

  • show_minima (bool, default=True) – Show markers at local minima

  • figsize (tuple, optional) – Figure size

  • ax (plt.Axes, optional) – Existing axes

Returns:

fig, ax (matplotlib figure and axes)

plot_tuning(tuning: List[float] | None = None, peaks: ndarray | None = None, ratios: List[float] | None = None, metric: str = 'harmsim', ratio_type: str = 'all', vmin: float | None = None, vmax: float | None = None, panels: int = 4, extra_panels: List[str] | None = None, show_summary: bool = True, show_source_curve: bool = True, max_denom: int = 100, figsize: Tuple[float, float] | None = None, **kwargs) Figure#

Plot comprehensive tuning analysis summary with 2, 4, or 5 panels.

For individual plots, use plot_tuning_scale(), plot_tuning_matrix(), plot_tuning_dissonance(), plot_tuning_entropy(), or plot_tuning_harmonic().

Parameters:
  • tuning (list of float, optional) – Tuning scale (e.g., diss_scale, HE_scale, harmonic_tuning). If provided, will use this directly for all panels.

  • peaks (np.ndarray, optional) – Spectral peaks (for computing ratios if tuning not provided)

  • ratios (list of float, optional) – Pre-computed peak ratios (fallback if neither tuning nor peaks provided)

  • metric (str, default=’harmsim’) – Metric for consonance matrix: - ‘harmsim’: Harmonic similarity (Gill & Purves) - higher = more consonant - ‘cons’: Consonance (a+b)/(a*b) - higher = more consonant - ‘tenney’: Tenney height - lower = more consonant (inverted for display) - ‘denom’: Denominator complexity - lower = more consonant (inverted for display) - ‘subharm_tension’: Subharmonic tension - lower = more consonant (inverted)

  • ratio_type (str, default=’all’) – Type of ratios to compute in matrix: - ‘pos_harm’: Only positive harmonics (a/b when a>b) - ‘sub_harm’: Only subharmonics (a/b when a<b) - ‘all’: Both positive and subharmonics

  • vmin (float, optional) – Minimum value for color scale (auto-adjusted if None)

  • vmax (float, optional) – Maximum value for color scale (auto-adjusted if None)

  • panels (int, default=4) – Number of panels (2, 4, or 5 with summary): - 2: Tuning scale + Consonance matrix - 4: Tuning scale + Consonance matrix + Step sizes + Consonance profile - 5: All above + Summary panel (if show_summary=True)

  • extra_panels (list of str, optional) – Custom extra panels for 4-panel mode: - ‘step_sizes’: Melodic interval sizes between adjacent notes - ‘consonance_profile’: Average consonance of each scale degree - ‘interval_distribution’: Histogram of all interval sizes in tuning - ‘harmonic_deviation’: Deviation from ideal harmonic ratios Default: [‘step_sizes’, ‘consonance_profile’]

  • show_summary (bool, default=True) – If True, adds a 5th panel with overall harmonicity and interval matches

  • show_source_curve (bool, default=True) – If True and tuning is ‘diss_curve’ or ‘HE’, shows the source curve (dissonance or entropy) as a top full-width panel. Requires biotuner object passed via bt_object kwarg.

  • max_denom (int, default=100) – Maximum denominator for fraction simplification when displaying ratios. Converts float ratios to fractions (e.g., 5/4 instead of 1.25). Lower values produce simpler fractions. Default 100 works well for most scales.

  • figsize (tuple, optional) – Figure size (auto-adjusted based on panels if None)

Returns:

fig (matplotlib figure)

plot_harmonic_fit(peaks: ndarray, amps: ndarray, freqs: ndarray, psd: ndarray, harm_fit: list, harmonics_pos: list, common_harms: list, matching_pos: list, extended_peaks: ndarray | None = None, extended_amps: ndarray | None = None, n_harm: int = 10, harm_bounds: float = 0.5, function: str = 'mult', xmin: float = 1, xmax: float = 60, show_bands: bool = True, figsize: tuple = (16, 12), **kwargs) Tuple[Figure, ndarray]#

Create comprehensive harmonic fit visualization with 4 panels.

Panels: 1. Top-left: Harmonic network graph 2. Top-right: Shared harmonic positions & distribution 3. Bottom-left: Harmonic connectivity matrix 4. Bottom-right: Harmonic position distribution

Parameters:
  • peaks (np.ndarray) – Original peak frequencies

  • amps (np.ndarray) – Peak amplitudes

  • freqs (np.ndarray) – Full frequency array from PSD

  • psd (np.ndarray) – Power spectral density values

  • harm_fit (list) – Fitted harmonic frequencies

  • harmonics_pos (list) – Harmonic positions that matched

  • common_harms (list) – Most common harmonic positions

  • matching_pos (list) – Detailed matching position information

  • extended_peaks (np.ndarray, optional) – Extended peaks from peaks_extension

  • extended_amps (np.ndarray, optional) – Extended peak amplitudes

  • n_harm (int, default=10) – Number of harmonics computed

  • harm_bounds (float, default=0.5) – Harmonic fit boundary threshold

  • function (str, default=’mult’) – Harmonic function used (‘mult’, ‘div’, ‘exp’)

  • xmin, xmax (float) – Frequency range for visualization

  • show_bands (bool, default=True) – Whether to show EEG frequency bands

  • figsize (tuple, default=(16, 12)) – Figure size

Returns:

  • fig (matplotlib.figure.Figure) – Figure object

  • axes (np.ndarray) – 2x2 array of axes

plot_harmonic_position_mappings(peaks: ndarray, amps: ndarray, multi_harmonics: ndarray, n_harm: int = 10, harm_bounds: float = 0.5, function: str = 'mult', figsize: tuple = (14, 10), **kwargs) Tuple[Figure, Axes][source]#

Plot harmonic position mappings between peak pairs in a circular network layout.

Shows which specific harmonic positions (1st, 2nd, 3rd, etc.) of one peak match with which harmonic positions of another peak. Edges are labeled with the matching harmonic positions (e.g., “2nd↔5th” means the 2nd harmonic of one peak matches the 5th harmonic of another).

Parameters:
  • peaks (np.ndarray) – Peak frequencies in Hz

  • amps (np.ndarray) – Peak amplitudes

  • multi_harmonics (np.ndarray) – Pre-computed harmonic series for each peak (n_peaks x n_harm)

  • n_harm (int, default=10) – Number of harmonics per peak

  • harm_bounds (float, default=0.5) – Frequency threshold (Hz) for considering harmonics as matching

  • function (str, default=’mult’) – Harmonic function used (‘mult’ or ‘div’)

  • figsize (tuple, default=(14, 10)) – Figure size

Returns:

  • fig (matplotlib.figure.Figure) – Figure object

  • ax (matplotlib.axes.Axes) – Axes object