Plotting Module

plotting.py

Active visualization functions for the exo2micro pipeline.

Includes:
  • Registration pipeline check plots (boundary extraction, alignment)

  • Pre/post diagnostic plots (heatmap, histograms, ratio histogram)

  • Excess signal heatmap (diagonal reflection)

  • Difference image visualization

  • Simple image display

Legacy plotting functions (plot_im_sub, plot_diff_comparison, plot_stretch_comparison, plot_zoom_region, plot_signal_scatter, plot_ratio_histogram, plot_residual_histogram) have been moved to exo2micro.legacy.

All plots include sample and dye in the title when provided.

exo2micro.plotting.plot_difference_histogram(post_im, pre_im, sample='', dye='', save_path=None)[source]

Histogram of raw pixel-wise difference (post - pre).

Three overlaid distributions: - All pixels (outline only) - Pixels where post > 0 and pre == 0 (post-only signal) - Pixels where both post > 0 and pre > 0 (shared signal)

Linear x-axis, log y-axis.

Parameters:
  • post_im (ndarray (2-D, float-like)) – Post-stain and aligned pre-stain images.

  • pre_im (ndarray (2-D, float-like)) – Post-stain and aligned pre-stain images.

  • sample (str) – For title.

  • dye (str) – For title.

  • save_path (str or None) – If set, save figure to this path.

Returns:

fig

Return type:

matplotlib.Figure

exo2micro.plotting.plot_difference_image(post_im, pre_im, scale, sample='', dye='', save_path=None)[source]

Plot the scaled difference image: post − scale × pre.

Shows the image with an asinh stretch and a diverging colormap so positive (microbe) signal is visually distinct from negative (over-subtraction) regions.

Parameters:
  • post_im (ndarray (2-D, float-like)) – Post-stain and aligned pre-stain images.

  • pre_im (ndarray (2-D, float-like)) – Post-stain and aligned pre-stain images.

  • scale (float) – Scale factor to apply to pre-stain before subtraction.

  • sample (str) – For title.

  • dye (str) – For title.

  • save_path (str or None) – If set, save figure to this path.

Returns:

  • fig (matplotlib.Figure)

  • diff (ndarray) – The difference image (float32).

exo2micro.plotting.plot_excess_heatmap(post_im, pre_im, scale=None, scales=None, sample='', dye='', save_path=None)[source]

Excess post-stain signal heatmap (upper triangle only).

Bins both axes by the actual integer values present in the post-stain data, then displays the post-excess asymmetry grid grid.T only above the diagonal (where post > pre). The lower triangle is masked to NaN because, by construction, grid grid.T is antisymmetric: every cell below the diagonal is the negative of its reflection above. There is no additional information in the lower half — displaying it would just be showing the same numbers with flipped sign on the wrong side of the line. Restricting the display to the upper triangle gives a single, unambiguous answer to the question “where in the brightness space is post brighter than pre, and by how much?”.

Cells with positive excess (post-stain pixels outnumber the reflected pre-stain pixels) are coloured by log₁₀(excess) using a sequential magma palette. Cells with zero or negative excess in the upper triangle are also masked to NaN — these correspond to brightness pairs where pre-stain pixels are actually MORE common than post (a possible sign of bleaching, quenching, or alignment artifact).

Optionally overplots one or more estimated scale lines.

Parameters:
  • post_im (ndarray (2-D, float-like)) – Post-stain and aligned pre-stain images.

  • pre_im (ndarray (2-D, float-like)) – Post-stain and aligned pre-stain images.

  • scale (float or None) – Single scale line to overplot (legacy convenience; equivalent to passing scales=[('scale', scale, '#00cc88')]).

  • scales (list of tuple or None) –

    List of (label, value, color) tuples to overplot as scale lines. Takes precedence over scale when both are given. Typical usage:

    scales=[
        ('Moffat fit',  1.123, '#00cc88'),
        ('ratio p99.1', 1.456, '#ff9933'),
        ('manual',      1.500, '#ff3366'),
    ]
    

  • sample (str) – For title.

  • dye (str) – For title.

  • save_path (str or None) – If set, save figure to this path.

Returns:

fig

Return type:

matplotlib.Figure

exo2micro.plotting.plot_fine_alignment(post_raw, pre_coarse_raw, pre_refined_raw, post_bnd, pre_coarse_bnd, pre_refined_bnd, title='Fine alignment', save_path=None, sample='', dye='')[source]

Two-panel comparison of coarse vs ICP-refined alignment.

Parameters:
  • post_raw (ndarray) – Post-stain image (downsampled, float32).

  • pre_coarse_raw (ndarray) – Pre-stain warped by coarse transform.

  • pre_refined_raw (ndarray) – Pre-stain warped by ICP-refined transform.

  • post_bnd (ndarray) – Post-stain boundary ring.

  • pre_coarse_bnd (ndarray) – Pre-stain boundary after coarse alignment.

  • pre_refined_bnd (ndarray) – Pre-stain boundary after ICP refinement.

  • title (str) – Figure title.

  • save_path (str or None) – If set, save to this path.

  • sample (str) – For title prefix.

  • dye (str) – For title prefix.

Returns:

fig

Return type:

matplotlib.Figure

exo2micro.plotting.plot_im(im, lims=None)[source]

Display a single image with auto-scaled or user-specified colorbar.

Parameters:
  • im (ndarray)

  • lims (list or None) – [vmin, vmax] display limits.

exo2micro.plotting.plot_pre_post_heatmap(post_im, pre_im, sample='', dye='', save_path=None)[source]

2-D density heatmap of pre-stain vs post-stain pixel brightness.

Uses ALL pixels. The y-axis (post-stain) is binned by the actual integer values present in the data, collapsing empty quantization gaps without smoothing or interpolation. The x-axis (pre-stain) uses standard integer bins.

Parameters:
  • post_im (ndarray (2-D, float-like)) – Post-stain and aligned pre-stain images.

  • pre_im (ndarray (2-D, float-like)) – Post-stain and aligned pre-stain images.

  • sample (str) – For title.

  • dye (str) – For title.

  • save_path (str or None) – If set, save figure to this path.

Returns:

fig

Return type:

matplotlib.Figure

exo2micro.plotting.plot_pre_post_histograms(post_im, pre_im, raw_pre_im=None, sample='', dye='', save_path=None)[source]

Overlapping histograms of pre-stain and post-stain pixel values.

Apples-to-apples comparison: when raw_pre_im is provided, the foreground pre histogram uses the raw padded pre-stain image (discrete 8-bit values, no warp interpolation), making it directly comparable to the post histogram which is also discrete 8-bit. The warped/interpolated pre is drawn underneath in faint grey for reference so the effect of the alignment warp on the distribution is still visible.

Padding-region zeros (where both pre and post are 0) are excluded via a sample-region mask defined as (post > 0) | (pre > 0). Interior dark pixels (zero in the sample region) are retained.

Bin edges are integer-aligned (-0.5, 0.5, …) and adapt to the actual range and density of observed values to avoid empty bins when the data are sparse.

The y-axis is linear by default; if the zero-value bin is more than 5× taller than the next-tallest bin (a common situation when the sample has lots of interior dark pixels), the y-axis switches to log so the rest of the distribution remains visible.

Parameters:
  • post_im (ndarray (2-D, float-like)) – Post-stain image (the reference frame, always 01_padded_post).

  • pre_im (ndarray (2-D, float-like)) – Aligned (warped, interpolated) pre-stain image (03_interior_aligned_pre or 02_icp_aligned_pre). Plotted in faint grey as a background reference.

  • raw_pre_im (ndarray (2-D, float-like) or None) – Raw padded pre-stain image (01_padded_pre) — discrete 8-bit values, no warp interpolation. When provided this is the apples-to-apples comparison to the post histogram and is plotted in the foreground. When None (legacy callers), the function falls back to the previous two-curve behaviour: warped pre and post only.

  • sample (str) – For title.

  • dye (str) – For title.

  • save_path (str or None) – If set, save figure to this path.

Returns:

fig

Return type:

matplotlib.Figure

exo2micro.plotting.plot_ratio_histogram_simple(post_im, pre_im, n_bins=200, smooth_sigma=3, sample='', dye='', save_path=None)[source]

Histogram of per-pixel post/pre ratio with scale estimation.

Plotted in log₁₀ space. Estimates the background scale factor from the smoothed histogram peak, then mirrors the left wing across the peak and fits a Moffat profile to model the noise.

Parameters:
  • post_im (ndarray (2-D, float-like)) – Post-stain and aligned pre-stain images.

  • pre_im (ndarray (2-D, float-like)) – Post-stain and aligned pre-stain images.

  • n_bins (int) – Number of histogram bins (default 200).

  • smooth_sigma (float) – Gaussian smoothing sigma (in bins) for peak finding (default 3).

  • sample (str) – For title.

  • dye (str) – For title.

  • save_path (str or None) – If set, save figure to this path.

Returns:

  • fig (matplotlib.Figure)

  • scale_estimate (float) – Estimated background scale factor (in linear units).

exo2micro.plotting.plot_registration(stages, title='Registration', save_path=None, sample='', dye='')[source]

Four-panel pipeline check figure for registration quality.

Panel 1a: Post-stain boundary extraction (cyan contour) Panel 1b: Pre-stain boundary extraction (magenta contour) Panel 2: Coarse alignment (both boundaries overlaid) Panel 3: Final difference image (post - pre, unscaled)

Parameters:
  • stages (list of dict) – Stage dicts from register_highorder debug_data[‘stages’].

  • title (str) – Figure title (default ‘Registration’).

  • save_path (str or None) – If set, save to this path.

  • sample (str) – For title prefix.

  • dye (str) – For title prefix.

Returns:

fig

Return type:

matplotlib.Figure or None

exo2micro.plotting.plot_zoom(image, row, col, size, sigma=0.0, cmap='gray', stretch_percentile=99.0, diverging=False, title='', save_path=None)[source]

Crop a square region from an image, optionally smooth it, and display.

Useful for inspecting fine structure in large microscopy images or difference images. The crop is bounds-checked so near-edge coordinates work without raising.

Parameters:
  • image (ndarray (2-D)) – Source image to crop from. Can be any float or integer dtype.

  • row (int) – Top-left corner of the crop region in pixel coordinates.

  • col (int) – Top-left corner of the crop region in pixel coordinates.

  • size (int) – Side length of the square crop in pixels.

  • sigma (float) – Gaussian blur sigma applied to the crop (default 0 = no blur).

  • cmap (str) – Matplotlib colormap name (default ‘gray’). Ignored if diverging=True.

  • stretch_percentile (float) – For non-diverging display, clip values above this percentile of the crop for display (default 99.0). Lower values push faint features harder.

  • diverging (bool) – If True, use a symmetric diverging colormap centred at zero (appropriate for difference images). Overrides cmap.

  • title (str) – Figure title.

  • save_path (str or None) – If set, save figure to this path.

Returns:

  • fig (matplotlib.Figure)

  • crop (ndarray (2-D)) – The cropped (and smoothed, if sigma > 0) region.

exo2micro.plotting.plot_zoom_multi(images, labels, row, col, size, sigma=0.0, cmaps=None, diverging_flags=None, stretch_percentile=99.0, sample='', dye='', save_path=None)[source]

Side-by-side zoomed crops from multiple images at the same coordinates.

Useful for comparing post-stain, aligned pre-stain, and difference image at a common region of interest.

Parameters:
  • images (list of ndarray) – 2-D images to crop from. All must have the same shape.

  • labels (list of str) – Panel titles, one per image.

  • row (int / int / int / float) – Crop geometry and blur, as in plot_zoom().

  • col (int / int / int / float) – Crop geometry and blur, as in plot_zoom().

  • size (int / int / int / float) – Crop geometry and blur, as in plot_zoom().

  • sigma (int / int / int / float) – Crop geometry and blur, as in plot_zoom().

  • cmaps (list of str or None) – Per-image colormap names. Default: ‘gray’ for each.

  • diverging_flags (list of bool or None) – If set, per-image flag to use a diverging symmetric colormap (typically True for the difference image).

  • stretch_percentile (float) – Display stretch percentile.

  • sample (str) – For title prefix.

  • dye (str) – For title prefix.

  • save_path (str or None) – If set, save figure to this path.

Returns:

  • fig (matplotlib.Figure)

  • crops (list of ndarray)