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