Visualization Module

The homodyne.viz module provides comprehensive visualization utilities for homodyne scattering analysis, including experimental data plots, optimization results, and MCMC diagnostics.

Overview

Visualization Categories:

  • Experimental Data: C2 heatmaps, time series, angular dependence

  • NLSQ Results: Fit comparisons, residuals, parameter correlations

  • MCMC Diagnostics: Trace plots, posterior distributions, convergence metrics

  • Performance: Datashader-accelerated plotting for large datasets

Key Features:

  • Adaptive color scaling for C2 heatmaps

  • High-performance rendering with Datashader (optional)

  • ArviZ integration for MCMC diagnostics

  • Publication-quality figure generation

Module Contents

Visualization backends for homodyne XPCS analysis.

This module provides high-performance visualization backends for C2 heatmap plotting and comprehensive MCMC diagnostic plots.

Experimental Data Plots

Visualization of experimental XPCS data.

Experimental data plotting functions for homodyne XPCS analysis.

This module provides functions for visualizing raw experimental C2 correlation data. Extracted from cli/commands.py for better modularity.

homodyne.viz.experimental_plots.plot_experimental_data(data, plots_dir, angle_filter_func=None)[source]

Generate validation plots of experimental data.

Parameters:
  • data (dict[str, Any]) – Data dictionary containing: - c2_exp: Experimental correlation data (n_phi, n_t1, n_t2) or (n_t1, n_t2) - t1: Time array 1 (optional) - t2: Time array 2 (optional) - phi_angles_list: Phi angles in degrees (optional) - config: Configuration dict for angle filtering (optional)

  • plots_dir (Path) – Output directory for plot files

  • angle_filter_func (Any | None) – Function to apply angle filtering. Signature: (phi_angles, c2_exp, data) -> (filtered_indices, filtered_phi, filtered_c2)

Return type:

None

homodyne.viz.experimental_plots.plot_fit_comparison(result, data, plots_dir)[source]

Generate comparison plots between fit and experimental data.

Parameters:
  • result (Any) – Optimization result object

  • data (dict[str, Any]) – Experimental data dictionary

  • plots_dir (Path) – Output directory for plot files

Return type:

None

Key Functions

homodyne.viz.experimental_plots.plot_experimental_data

Generate validation plots of experimental data.

homodyne.viz.experimental_plots.plot_fit_comparison

Generate comparison plots between fit and experimental data.

C2 Heatmap Plotting

Adaptive Color Scaling:

All C2 heatmap plots use conditional color scaling logic:

vmin = max(1.0, c2_min)  # Use data_min if >= 1.0, else clamp to 1.0
vmax = min(1.6, c2_max)  # Use data_max if <= 1.6, else clamp to 1.6

This ensures physically meaningful visualization while preventing extreme outliers from dominating the color scale.

Usage Example

from pathlib import Path
from homodyne.viz import plot_experimental_data, plot_fit_comparison

# Plot experimental C2 heatmaps (saves to plots_dir)
plot_experimental_data(
    data=data,          # dict from XPCSDataLoader
    plots_dir=Path("plots/"),
)

# Compare fit to data (saves to plots_dir)
plot_fit_comparison(
    result=nlsq_result,  # optimization result object
    data=data,
    plots_dir=Path("plots/"),
)

NLSQ Optimization Plots

Visualization of NLSQ optimization results.

NLSQ optimization plotting functions for homodyne XPCS analysis.

This module provides functions for visualizing NLSQ optimization results, including simulated data, fitted data, and comparison heatmaps. Extracted from cli/commands.py for better modularity.

homodyne.viz.nlsq_plots.plot_simulated_data(config, contrast, offset, phi_angles_str, plots_dir, data=None)[source]

Generate plots of simulated/theoretical data.

Parameters:
  • config (dict[str, Any]) – Configuration dictionary with analysis_mode and parameters

  • contrast (float) – Contrast parameter value

  • offset (float) – Offset parameter value

  • phi_angles_str (str | None) – Comma-separated phi angles string from CLI

  • plots_dir (Path) – Output directory for plot files

  • data (dict[str, Any] | None) – Optional experimental data dictionary for extracting phi angles

Return type:

None

homodyne.viz.nlsq_plots.generate_and_plot_fitted_simulations(result, data, config, output_dir, angle_filter_func=None)[source]

Generate and plot C2 simulations using fitted parameters from optimization.

Parameters:
  • result (Any) – Optimization result containing fitted parameters

  • data (dict[str, Any]) – Experimental data dictionary containing phi_angles_list, t1, t2, c2_exp

  • config (dict[str, Any]) – Configuration dictionary with analysis_mode and physics parameters

  • output_dir (Path) – Output directory path (simulated_data/ subdirectory will be created)

  • angle_filter_func (Any | None) – Function to apply angle filtering for optimization

Return type:

None

homodyne.viz.nlsq_plots.generate_nlsq_plots(phi_angles, c2_exp, c2_theoretical_scaled, residuals, t1, t2, output_dir, config=None, use_datashader=True, parallel=True, *, c2_solver_scaled=None)[source]

Generate 3-panel heatmap plots for NLSQ fit visualization.

Parameters:
  • phi_angles (ndarray) – Scattering angles in degrees (n_angles,)

  • c2_exp (ndarray) – Experimental correlation data (n_angles, n_t1, n_t2)

  • c2_theoretical_scaled (ndarray) – Scaled theoretical fits (n_angles, n_t1, n_t2)

  • residuals (ndarray) – Residuals: exp - scaled (n_angles, n_t1, n_t2)

  • t1 (ndarray) – Time array 1 in seconds (n_t1,)

  • t2 (ndarray) – Time array 2 in seconds (n_t2,)

  • output_dir (Path) – Output directory for PNG files

  • config (Any) – Configuration object/dict containing output.plots settings

  • use_datashader (bool) – Legacy parameter for backward compatibility

  • parallel (bool) – Generate plots in parallel using multiprocessing

  • c2_solver_scaled (ndarray | None) – Optional solver-computed scaled C2 for display

Return type:

None

Plot Generation

homodyne.viz.nlsq_plots.generate_nlsq_plots

Generate 3-panel heatmap plots for NLSQ fit visualization.

homodyne.viz.nlsq_plots.plot_simulated_data

Generate plots of simulated/theoretical data.

homodyne.viz.nlsq_plots.generate_and_plot_fitted_simulations

Generate and plot C2 simulations using fitted parameters from optimization.

Usage Example

from pathlib import Path
from homodyne.viz import generate_nlsq_plots

# Generate comprehensive NLSQ plots (saves to output_dir)
generate_nlsq_plots(
    phi_angles=phi_angles,
    c2_exp=c2_exp,
    c2_theoretical_scaled=c2_fitted,
    residuals=residuals,
    t1=t1,
    t2=t2,
    output_dir=Path("plots/"),
)

# Output includes:
# - Fit comparison heatmaps
# - Residual plots

MCMC Diagnostic Plots

Comprehensive MCMC convergence and posterior diagnostics. The implementation is split across focused submodules; mcmc_plots re-exports all public names.

MCMC Diagnostic Visualization Module

This module provides comprehensive diagnostic plots for MCMC results including both standard NUTS MCMC and Consensus Monte Carlo (CMC) results.

Features: - Trace plots for convergence visualization - KL divergence matrix heatmaps for CMC shard agreement - Convergence diagnostics (R-hat, ESS) visualization - Posterior distribution comparison plots - Comprehensive multi-panel summary dashboard

Supported Result Types: - Standard NUTS MCMC results (single posterior) - CMC results with per-shard diagnostics (multiple subposteriors)

References

Scott et al. (2016): “Bayes and big data: the consensus Monte Carlo algorithm” Gelman et al. (2013): “Bayesian Data Analysis”

Examples

# Plot trace plots for standard NUTS result >>> from homodyne.optimization.cmc import fit_mcmc_jax >>> result = fit_mcmc_jax(data=c2_exp, t1=t1, t2=t2, phi=phi, q=0.01, L=3.5) >>> plot_trace_plots(result, save_path=’traces.png’)

# Create CMC summary dashboard >>> result_cmc = fit_mcmc_jax(data=large_data, method=’cmc’, …) >>> plot_cmc_summary_dashboard(result_cmc, save_path=’cmc_summary.png’)

MCMC Convergence Diagnostics Visualization.

Provides trace plots, KL divergence matrix heatmaps, and convergence diagnostics (R-hat, ESS) for NUTS and CMC results.

homodyne.viz.mcmc_diagnostics.plot_trace_plots(result, param_names=None, max_params=9, figsize=None, show=False, save_path=None, dpi=150)[source]

Plot MCMC trace plots for convergence visualization.

Creates a grid of trace plots showing parameter evolution across MCMC samples. For CMC results, overlays traces from multiple shards with different colors.

Parameters:
  • result (Any) – MCMC or CMC result object containing samples

  • param_names (list[str] | None) – Parameter names to plot. If None, uses default names (param_0, param_1, …)

  • max_params (int) – Maximum number of parameters to plot (to avoid cluttered figures)

  • figsize (tuple[float, float] | None) – Figure size (width, height). If None, auto-calculated based on param count

  • show (bool) – If True, display the figure interactively

  • save_path (str | Path | None) – If provided, save figure to this path

  • dpi (int) – DPI for saved figure

Returns:

Matplotlib figure object

Return type:

Figure

Examples

>>> # Standard NUTS result
>>> plot_trace_plots(nuts_result, param_names=['D0', 'alpha', 'D_offset'])
>>> # CMC result with multiple shards
>>> plot_trace_plots(cmc_result, save_path='traces_cmc.png')

Notes

  • For NUTS: Single trace line per parameter

  • For CMC: Multiple colored lines (one per shard)

  • X-axis: Sample index (after warmup)

  • Y-axis: Parameter value

  • Good mixing: trace should look like “hairy caterpillar”

  • Poor mixing: trace shows trends or gets stuck

homodyne.viz.mcmc_diagnostics.plot_kl_divergence_matrix(result, figsize=(8, 7), cmap='coolwarm', threshold=2.0, show=False, save_path=None, dpi=150)[source]

Plot KL divergence matrix heatmap for CMC results.

Visualizes pairwise KL divergence between shards to assess posterior agreement. High KL divergence (>2.0) indicates shards found different posteriors.

Parameters:
  • result (Any) – CMC result object with cmc_diagnostics containing KL matrix

  • figsize (tuple[float, float]) – Figure size (width, height)

  • cmap (str) – Matplotlib colormap name (coolwarm shows cool=low, warm=high KL)

  • threshold (float) – KL divergence threshold to highlight (standard: 2.0)

  • show (bool) – If True, display the figure interactively

  • save_path (str | Path | None) – If provided, save figure to this path

  • dpi (int) – DPI for saved figure

Returns:

Matplotlib figure object

Return type:

Figure

Raises:

ValueError – If result is not a CMC result or KL matrix not available

Examples

>>> plot_kl_divergence_matrix(cmc_result, threshold=2.0, save_path='kl_matrix.png')

Notes

  • Diagonal elements are 0.0 (self-divergence)

  • Matrix is symmetric by construction (averaged KL)

  • Values < 0.5: Excellent agreement

  • Values 0.5-2.0: Acceptable agreement

  • Values > 2.0: Poor agreement (possible multimodality)

homodyne.viz.mcmc_diagnostics.plot_convergence_diagnostics(result, metrics=None, figsize=None, rhat_threshold=1.1, ess_threshold=400.0, show=False, save_path=None, dpi=150)[source]

Plot convergence diagnostics (R-hat and ESS) for MCMC results.

Visualizes convergence metrics to assess MCMC sampling quality. For CMC results, shows per-shard and combined diagnostics.

Parameters:
  • result (Any) – MCMC or CMC result object with convergence diagnostics

  • metrics (list[str] | None) – Metrics to plot. Options: ‘rhat’, ‘ess’. Defaults to [‘rhat’, ‘ess’]

  • figsize (tuple[float, float] | None) – Figure size (width, height). If None, auto-calculated

  • rhat_threshold (float) – R-hat threshold for convergence (standard: 1.1)

  • ess_threshold (float) – ESS threshold for adequate sampling (standard: 400)

  • show (bool) – If True, display the figure interactively

  • save_path (str | Path | None) – If provided, save figure to this path

  • dpi (int) – DPI for saved figure

Returns:

Matplotlib figure object

Return type:

Figure

Examples

>>> plot_convergence_diagnostics(result, metrics=['rhat', 'ess'])
>>> # CMC result with per-shard diagnostics
>>> plot_convergence_diagnostics(cmc_result, save_path='convergence.png')

Notes

  • R-hat < 1.1: Converged (good)

  • R-hat > 1.1: Not converged (bad)

  • ESS > 100: Adequate sampling (good)

  • ESS < 100: Poor sampling efficiency (bad)

homodyne.viz.mcmc_diagnostics.compute_bfmi(energy, *, per_chain=False)[source]

Compute Bayesian Fraction of Missing Information (BFMI).

BFMI measures how well the kinetic energy in HMC/NUTS matches the marginal energy distribution. Low BFMI (< 0.3) indicates the sampler is struggling with the posterior geometry (e.g., funnel shapes, poor mass matrix adaptation).

Parameters:
  • energy (ndarray) – Potential energy trace. Shape: (n_samples,) for single chain, or (n_chains, n_samples) for multi-chain.

  • per_chain (bool) – If True and energy is multi-chain, return BFMI per chain. If False, return pooled BFMI across all chains.

Returns:

BFMI value(s). Range [0, inf), typically [0, 2]. - < 0.3: Poor energy transitions (flag for review) - 0.3 - 1.0: Acceptable - > 1.0: Good energy mixing

Return type:

float | ndarray

MCMC Posterior Comparison Visualization.

Provides per-shard vs combined posterior distribution comparisons for CMC results.

homodyne.viz.mcmc_comparison.plot_posterior_comparison(result, param_indices=None, figsize=None, bins=30, show=False, save_path=None, dpi=150)[source]

Compare per-shard posteriors with combined posterior (CMC only).

Visualizes posterior distributions for each parameter, showing both per-shard distributions and the combined posterior.

Parameters:
  • result (Any) – CMC result object with per-shard diagnostics

  • param_indices (list[int] | None) – Parameter indices to plot. If None, plots first 6 parameters

  • figsize (tuple[float, float] | None) – Figure size (width, height). If None, auto-calculated

  • bins (int) – Number of bins for histograms

  • show (bool) – If True, display the figure interactively

  • save_path (str | Path | None) – If provided, save figure to this path

  • dpi (int) – DPI for saved figure

Returns:

Matplotlib figure object

Return type:

Figure

Raises:

ValueError – If result is not a CMC result

Examples

>>> plot_posterior_comparison(cmc_result, param_indices=[0, 1, 2])

Notes

  • Light colored lines: Per-shard posteriors

  • Bold colored line: Combined posterior

  • Good agreement: All distributions overlap

  • Poor agreement: Shards show different modes

MCMC Summary Dashboard Visualization.

Provides a comprehensive multi-panel CMC summary dashboard combining KL divergence, convergence diagnostics, trace plots, and posterior histograms.

homodyne.viz.mcmc_dashboard.plot_cmc_summary_dashboard(result, figsize=(16, 12), show=False, save_path=None, dpi=150)[source]

Create comprehensive multi-panel CMC summary dashboard.

Combines all diagnostic plots into a single comprehensive figure: - Panel 1: KL divergence matrix - Panel 2: Convergence diagnostics (R-hat, ESS) - Panel 3: Trace plots (selected parameters) - Panel 4: Posterior comparison

Parameters:
  • result (Any) – CMC result object

  • figsize (tuple[float, float]) – Figure size (width, height)

  • show (bool) – If True, display the figure interactively

  • save_path (str | Path | None) – If provided, save figure to this path

  • dpi (int) – DPI for saved figure

Returns:

Matplotlib figure object

Return type:

Figure

Raises:

ValueError – If result is not a CMC result

Examples

>>> plot_cmc_summary_dashboard(cmc_result, save_path='cmc_summary.png')

Notes

This is the primary diagnostic tool for CMC results. It provides a comprehensive overview of convergence, agreement between shards, and posterior quality in a single figure.

ArviZ-Based MCMC Plotting Functions.

Provides ArviZ-powered trace, posterior, and pair plots for MCMC/CMC results. Falls back gracefully when ArviZ is not installed.

homodyne.viz.mcmc_arviz.plot_arviz_trace(result, var_names=None, figsize=None, show=False, save_path=None, dpi=150, **kwargs)[source]

Plot MCMC trace plots using ArviZ.

Creates trace plots showing parameter evolution and posterior distributions side by side for each parameter.

Parameters:
  • result (Any) – MCMC or CMC result object containing samples.

  • var_names (list[str] | None) – Parameter names to plot. If None, plots all parameters.

  • figsize (tuple[float, float] | None) – Figure size (width, height). If None, auto-calculated.

  • show (bool) – If True, display the figure interactively.

  • save_path (str | Path | None) – If provided, save figure to this path.

  • dpi (int) – DPI for saved figure.

  • **kwargs (Any) – Additional arguments passed to az.plot_trace().

Returns:

Matplotlib figure object.

Return type:

Figure

Examples

>>> plot_arviz_trace(result, var_names=["D0", "alpha", "D_offset"])
>>> plot_arviz_trace(result, save_path="traces.png")
homodyne.viz.mcmc_arviz.plot_arviz_posterior(result, var_names=None, hdi_prob=0.95, figsize=None, show=False, save_path=None, dpi=150, **kwargs)[source]

Plot posterior distributions with 95% credible intervals using ArviZ.

Parameters:
  • result (Any) – MCMC or CMC result object containing samples.

  • var_names (list[str] | None) – Parameter names to plot. If None, plots all parameters.

  • hdi_prob (float) – Highest density interval probability (e.g., 0.95 for 95% HDI).

  • figsize (tuple[float, float] | None) – Figure size (width, height). If None, auto-calculated.

  • show (bool) – If True, display the figure interactively.

  • save_path (str | Path | None) – If provided, save figure to this path.

  • dpi (int) – DPI for saved figure.

  • **kwargs (Any) – Additional arguments passed to az.plot_posterior().

Returns:

Matplotlib figure object.

Return type:

Figure

Examples

>>> plot_arviz_posterior(result, var_names=["D0", "alpha", "D_offset"])
>>> plot_arviz_posterior(result, hdi_prob=0.90)  # 90% CI
homodyne.viz.mcmc_arviz.plot_arviz_pair(result, var_names=None, figsize=None, show=False, save_path=None, dpi=150, **kwargs)[source]

Plot pair plots showing parameter correlations using ArviZ.

Parameters:
  • result (Any) – MCMC or CMC result object containing samples.

  • var_names (list[str] | None) – Parameter names to plot. If None, plots physical parameters only.

  • figsize (tuple[float, float] | None) – Figure size (width, height). If None, auto-calculated.

  • show (bool) – If True, display the figure interactively.

  • save_path (str | Path | None) – If provided, save figure to this path.

  • dpi (int) – DPI for saved figure.

  • **kwargs (Any) – Additional arguments passed to az.plot_pair().

Returns:

Matplotlib figure object.

Return type:

Figure

Examples

>>> plot_arviz_pair(result, var_names=["D0", "alpha", "D_offset"])
>>> plot_arviz_pair(result)  # Auto-selects physical parameters

MCMC Diagnostic Report Generation.

Provides functions to generate comprehensive diagnostic reports (all plots) and print formatted MCMC summaries to the console.

homodyne.viz.mcmc_report.generate_mcmc_diagnostic_report(result, output_dir, prefix='mcmc', include_heatmaps=True, dpi=150)[source]

Generate comprehensive MCMC diagnostic report with all plots.

Creates a complete set of diagnostic plots for MCMC results: 1. ArviZ trace plots (trace + posterior side-by-side) 2. ArviZ posterior distributions with 95% CI 3. ArviZ pair plots (parameter correlations) 4. Convergence diagnostics (R-hat, ESS) 5. CMC-specific: KL divergence matrix, shard comparison

Parameters:
  • result (Any) – MCMC or CMC result object.

  • output_dir (str | Path) – Directory to save plots.

  • prefix (str) – Prefix for output filenames.

  • include_heatmaps (bool) – Whether to include C2 heatmap comparisons (requires fitted_data).

  • dpi (int) – DPI for saved figures.

Returns:

Dictionary mapping plot names to file paths.

Return type:

dict[str, Path]

Examples

>>> paths = generate_mcmc_diagnostic_report(result, "output/mcmc_diagnostics")
>>> print(paths["trace"])  # Path to trace plot
>>> print(paths["posterior"])  # Path to posterior plot
homodyne.viz.mcmc_report.print_mcmc_summary(result)[source]

Print formatted MCMC summary to console.

Displays key diagnostics including: - Parameter estimates with 95% CI - R-hat and ESS for each parameter - Convergence status - CMC-specific information if applicable

Parameters:

result (Any) – MCMC or CMC result object.

Return type:

None

Examples

>>> print_mcmc_summary(result)

Diagnostic Functions

homodyne.viz.mcmc_plots.plot_trace_plots

Plot MCMC trace plots for convergence visualization.

homodyne.viz.mcmc_plots.plot_convergence_diagnostics

Plot convergence diagnostics (R-hat and ESS) for MCMC results.

homodyne.viz.mcmc_plots.plot_posterior_comparison

Compare per-shard posteriors with combined posterior (CMC only).

homodyne.viz.mcmc_plots.plot_kl_divergence_matrix

Plot KL divergence matrix heatmap for CMC results.

homodyne.viz.mcmc_plots.plot_cmc_summary_dashboard

Create comprehensive multi-panel CMC summary dashboard.

Trace Plots

from homodyne.viz import plot_trace_plots

# Plot MCMC traces for all parameters (saves to save_path)
plot_trace_plots(
    result=cmc_result,
    save_path="trace_plots.png",
)

Trace plots show:

  • Time series of sampled parameter values

  • Multiple chains (for convergence assessment)

  • Burn-in period visualization

  • Mixing quality

Convergence Diagnostics

from homodyne.viz import plot_convergence_diagnostics

# Plot R-hat and ESS diagnostics (saves to save_path)
plot_convergence_diagnostics(
    result=cmc_result,
    save_path="convergence.png",
)

Diagnostics include:

  • R-hat (Gelman-Rubin statistic): Should be < 1.01

  • ESS (Effective Sample Size): Higher is better

  • Autocorrelation plots

  • Chain comparison

Posterior Distributions

from homodyne.viz import plot_posterior_comparison

# Plot posterior distributions (saves to save_path)
plot_posterior_comparison(
    result=cmc_result,
    save_path="posteriors.png",
)

Posterior plots show:

  • Marginal distributions for each parameter

  • Credible intervals (94% HDI by default)

  • Prior vs. posterior comparison

  • Kernel density estimates

CMC Summary Dashboard

from homodyne.viz import plot_cmc_summary_dashboard

# Generate comprehensive CMC dashboard (saves to save_path)
plot_cmc_summary_dashboard(
    result=cmc_result,
    save_path="cmc_dashboard.png",
)

Dashboard includes:

  • Trace plots

  • Posterior distributions

  • Fit comparison

  • Convergence metrics

  • Parameter correlations

KL Divergence Matrix

from homodyne.viz import plot_kl_divergence_matrix

# Plot KL divergence between chains (saves to save_path)
plot_kl_divergence_matrix(
    result=cmc_result,
    save_path="kl_divergence.png",
)

KL divergence:

  • Measures agreement between chains

  • Low KL = good convergence

  • High KL = chains exploring different modes

Datashader Backend (Optional)

High-performance visualization for large datasets using Datashader.

Datashader backend for fast C2 heatmap visualization (CPU-only in v2.3.0+).

This module provides high-performance CPU-optimized heatmap rendering using Datashader, offering 5-10x speedup over matplotlib for C2 correlation data visualization.

Key features: - CPU-optimized rendering for HPC environments - Fast PNG generation for large datasets - Backward compatible with matplotlib output format - Parallel processing support for multi-angle plots

class homodyne.viz.datashader_backend.DatashaderRenderer[source]

Bases: object

Fast heatmap rendering using Datashader (CPU-only in v2.3.0+).

This renderer uses Datashader’s optimized CPU rasterization pipeline to convert 2D gridded data (C2 correlation matrices) into RGB images much faster than matplotlib’s imshow() + savefig() workflow.

Performance:
  • Typical speedup: 5-10x over matplotlib

  • Recommended for grids >100x100 or multiple plots

  • CPU-optimized for HPC environments

Examples

>>> renderer = DatashaderRenderer(width=800, height=800)
>>> img = renderer.rasterize_heatmap(c2_data, t2_coords, t1_coords)
>>> img.save('output.png')  # Direct PIL save, very fast
__init__(width=800, height=800)[source]

Initialize Datashader renderer (CPU-only in v2.3.0+).

Parameters:
  • width (int) – Output image width in pixels

  • height (int) – Output image height in pixels

rasterize_heatmap(data, x_coords, y_coords, cmap='jet', vmin=None, vmax=None)[source]

Rasterize 2D gridded data to PIL Image using Datashader.

This is 5-10x faster than matplotlib.imshow() + savefig() for typical C2 correlation data (50x50 to 200x200 grids).

The workflow: 1. Convert numpy array to xarray DataArray (Datashader’s native format) 2. Create canvas at target resolution (e.g., 800x800 pixels) 3. Rasterize data to canvas (regrid/resample) 4. Apply colormap and convert to RGB PIL Image

Parameters:
  • data (ndarray) – 2D array to rasterize, shape (n_y, n_x) For C2 data: pass c2.T to swap axes for correct display

  • x_coords (ndarray) – X-axis (horizontal) coordinates, shape (n_x,) For C2 data: pass t1 time array

  • y_coords (ndarray) – Y-axis (vertical) coordinates, shape (n_y,) For C2 data: pass t2 time array

  • cmap (str) – Colormap name. Supported: - ‘jet’ (default for all plots including residuals) - ‘viridis’, ‘plasma’, ‘inferno’, ‘magma’ (matplotlib perceptually uniform) - ‘coolwarm’, ‘RdBu_r’ (diverging, alternative for residuals) - Any matplotlib or colorcet colormap name

  • vmin (float | None) – Color scale limits. If None, auto-computed from data min/max.

  • vmax (float | None) – Color scale limits. If None, auto-computed from data min/max.

Returns:

PIL Image object in RGB format, ready for saving or display

Return type:

Image

Raises:

ValueError – If data dimensions don’t match coordinate arrays

Examples

>>> renderer = DatashaderRenderer(width=800, height=800)
>>> c2_data = np.random.rand(50, 50)
>>> t1 = np.linspace(0, 1, 50)
>>> t2 = np.linspace(0, 1, 50)
>>> img = renderer.rasterize_heatmap(c2_data, t2, t1, cmap='jet')
>>> img.save('c2_heatmap.png')
homodyne.viz.datashader_backend.plot_c2_heatmap_fast(c2_data, t1, t2, output_path, title='', phi_angle=None, cmap='jet', width=800, height=800, *, vmin=None, vmax=None, adaptive=False, percentile_min=1.0, percentile_max=99.0)[source]

Plot C2 heatmap using Datashader for fast CPU rendering.

This function uses Datashader for rasterization (5-10x faster than matplotlib) and matplotlib for annotations (colorbars, titles, labels).

Workflow: 1. Rasterize C2 data to RGB image with Datashader (fast CPU rendering) 2. Display RGB image in matplotlib figure (minimal overhead) 3. Add colorbar using original data values (not RGB) 4. Add title, labels, save PNG

Performance:
  • Matplotlib only: ~150ms per plot

  • Datashader CPU hybrid: ~30ms per plot (5x speedup)

Parameters:
  • c2_data (ndarray) – C2 correlation data, shape (n_t1, n_t2)

  • t1 (ndarray) – Time arrays, shapes (n_t1,) and (n_t2,)

  • t2 (ndarray) – Time arrays, shapes (n_t1,) and (n_t2,)

  • output_path (Path) – Output PNG file path

  • title (str) – Plot title (phi_angle will be appended if provided)

  • phi_angle (float | None) – Scattering angle in degrees (added to title)

  • cmap (str) – Colormap name

  • width (int) – Output image size in pixels (rasterization resolution)

  • height (int) – Output image size in pixels (rasterization resolution)

Return type:

None

Examples

>>> c2_data = np.random.rand(50, 50)
>>> t1 = np.linspace(0, 1, 50)
>>> t2 = np.linspace(0, 1, 50)
>>> plot_c2_heatmap_fast(
...     c2_data, t1, t2,
...     Path('c2_phi0.png'),
...     phi_angle=0.0
... )
homodyne.viz.datashader_backend.plot_c2_comparison_fast(c2_exp, c2_fit, residuals, t1, t2, output_path, phi_angle, width=800, height=800, *, vmin=None, vmax=None, adaptive=True, percentile_min=1.0, percentile_max=99.0)[source]

Generate 3-panel comparison plot using Datashader CPU rendering.

Replaces generate_nlsq_plots() with faster Datashader rendering. Creates side-by-side comparison: Experimental | Fitted | Residuals

Performance:
  • Matplotlib only: ~300ms per 3-panel plot

  • Datashader CPU hybrid: ~60ms per 3-panel plot (5x speedup)

Parameters:
  • c2_exp (ndarray) – Experimental correlation data, shape (n_t1, n_t2)

  • c2_fit (ndarray) – Fitted theoretical data, shape (n_t1, n_t2)

  • residuals (ndarray) – Residuals = exp - fit, shape (n_t1, n_t2)

  • t1 (ndarray) – Time arrays, shapes (n_t1,) and (n_t2,)

  • t2 (ndarray) – Time arrays, shapes (n_t1,) and (n_t2,)

  • output_path (Path) – Output PNG file path

  • phi_angle (float) – Scattering angle in degrees

  • width (int) – Individual panel size in pixels

  • height (int) – Individual panel size in pixels

  • vmin (float | None) – Explicit color scale limits. If None, computed adaptively.

  • vmax (float | None) – Explicit color scale limits. If None, computed adaptively.

  • adaptive (bool) – Use adaptive (percentile-based) color scaling from combined experimental AND fit data ranges. This prevents block artifacts when fit data has a narrower range than experimental data.

  • percentile_min (float) – Percentiles for adaptive color scale computation.

  • percentile_max (float) – Percentiles for adaptive color scale computation.

Return type:

None

Examples

>>> plot_c2_comparison_fast(
...     c2_exp, c2_fit, residuals,
...     t1, t2,
...     Path('comparison_phi_45.png'),
...     phi_angle=45.0
... )

Installation:

pip install datashader xarray colorcet

Fast Plotting

homodyne.viz.datashader_backend.plot_c2_heatmap_fast

Plot C2 heatmap using Datashader for fast CPU rendering.

homodyne.viz.datashader_backend.plot_c2_comparison_fast

Generate 3-panel comparison plot using Datashader CPU rendering.

homodyne.viz.datashader_backend.DatashaderRenderer

Fast heatmap rendering using Datashader (CPU-only in v2.3.0+).

Usage Example

from pathlib import Path
from homodyne.viz import plot_c2_heatmap_fast

# Fast rendering for large datasets (saves directly to output_path)
plot_c2_heatmap_fast(
    c2_data=c2_exp,
    t1=t1,
    t2=t2,
    output_path=Path("c2_fast.png"),
    title="Experimental C2",
)

Performance:

  • 10-100x faster than matplotlib for large arrays

  • Automatic downsampling for display

  • Preserves visual fidelity

  • Ideal for > 1000x1000 arrays

Visualization Diagnostics

Quantitative diagnostics for visualizations.

Diagnostic helpers for visual validation of fitted C₂ surfaces.

class homodyne.viz.diagnostics.DiagonalOverlayResult[source]

Bases: object

DiagonalOverlayResult(phi_index: ‘int’, raw_diagonal: ‘np.ndarray’, solver_diagonal: ‘np.ndarray’, posthoc_diagonal: ‘np.ndarray’, raw_variance: ‘float’, solver_variance: ‘float’, posthoc_variance: ‘float’, solver_rmse: ‘float’, posthoc_rmse: ‘float’)

phi_index: int
raw_diagonal: ndarray
solver_diagonal: ndarray
posthoc_diagonal: ndarray
raw_variance: float
solver_variance: float
posthoc_variance: float
solver_rmse: float
posthoc_rmse: float
__init__(phi_index, raw_diagonal, solver_diagonal, posthoc_diagonal, raw_variance, solver_variance, posthoc_variance, solver_rmse, posthoc_rmse)
homodyne.viz.diagnostics.compute_diagonal_overlay_stats(c2_exp, c2_solver, c2_posthoc, *, phi_index=0)[source]

Return diagonal traces and simple statistics for a single angle.

Return type:

DiagonalOverlayResult

Diagonal Overlay Stats

homodyne.viz.diagnostics.compute_diagonal_overlay_stats

Return diagonal traces and simple statistics for a single angle.

homodyne.viz.diagnostics.DiagonalOverlayResult

DiagonalOverlayResult(phi_index: 'int', raw_diagonal: 'np.ndarray', solver_diagonal: 'np.ndarray', posthoc_diagonal: 'np.ndarray', raw_variance: 'float', solver_variance: 'float', posthoc_variance: 'float', solver_rmse: 'float', posthoc_rmse: 'float')

Usage Example

from homodyne.viz import compute_diagonal_overlay_stats

# Compute statistics for diagonal overlay
stats = compute_diagonal_overlay_stats(
    c2_exp=c2_exp,
    c2_solver=c2_solver,
    c2_posthoc=c2_posthoc,
    phi_index=0,
)

# stats is a DiagonalOverlayResult with trace arrays and statistics

Publication-Quality Figures

Recommended Settings:

import matplotlib.pyplot as plt

# Set publication style
plt.rcParams['figure.dpi'] = 300
plt.rcParams['savefig.dpi'] = 300
plt.rcParams['font.size'] = 12
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['axes.labelsize'] = 14
plt.rcParams['axes.titlesize'] = 16

# Generate plot
from homodyne.viz import plot_experimental_data
fig = plot_experimental_data(...)

# Save with tight layout
fig.tight_layout()
fig.savefig("figure.pdf", bbox_inches='tight')

Figure Formats:

  • PNG: Web display, presentations

  • PDF: Publications, vector graphics

  • SVG: Editable vector graphics

  • EPS: Legacy publications

Color Maps

Default C2 Heatmap Colormap: viridis

  • Perceptually uniform

  • Colorblind-friendly

  • Good for grayscale printing

Alternative Colormaps:

  • plasma: Higher contrast

  • inferno: Warmer tones

  • cividis: Colorblind-optimized

Custom Colormap:

fig = plot_c2_heatmap_fast(
    ...,
    cmap='plasma'
)

Best Practices

Heatmap Visualization:

  1. Use adaptive color scaling (automatic)

  2. Include colorbars with physical units

  3. Label axes with time in seconds

  4. Add title with phi angle for multi-angle plots

MCMC Diagnostics:

  1. Always check trace plots for mixing

  2. Verify R-hat < 1.01 for all parameters

  3. Check ESS > 400 per chain (minimum)

  4. Plot posteriors vs. priors to assess learning

Performance:

  1. Use Datashader for datasets > 1000x1000

  2. Reduce DPI for exploratory plots (150)

  3. Save high-res only for final figures (300+)

  4. Close figures after saving to free memory

See Also