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:
- 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.Tonly above the diagonal (where post > pre). The lower triangle is masked to NaN because, by construction,grid − grid.Tis 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 overscalewhen 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:
- 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_imis 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_preor02_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. WhenNone(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:
- 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.
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)