Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

plotting.images

plotting.images

Attributes

NameDescription
GRID_FRAME_QUALITY
GRID_LOSSLESS_MAX_PIXELS
MRSI_FRAME_QUALITY
VoxelCoord
VoxelCoordsInput
VoxelStyle
VoxelStylesInput

Classes

NameDescription
VoxelOverlayParamsKeyword arguments accepted by overlay_voxel_on_T1.

VoxelOverlayParams

plotting.images.VoxelOverlayParams()

Keyword arguments accepted by overlay_voxel_on_T1.

Attributes

NameDescription
blocky
image_kwargs
overlay_kwargs
scale_overlay
show_overlay
title
voxel_kwargs

Functions

NameDescription
display_imagesDisplay a grid of 2D/3D/4D images, with a slice slider for 3D/4D input.
display_niftiOrient a NIfTI image and display it via display_images.
draw_voxel_overlays_on_axDraw voxel outlines on an axis.
fast_boundsQuickly estimate lower/upper display bounds by sampling a subset of the data.
get_voxel_visible_slice_rangeReturn inclusive third-dimension slice range where a voxel is visible.
inspect_MRSI_spectraDisplay an interactive widget to inspect MRSI spectra over a T1 image.
mrsi_spectra_for_displayBuild the exact ppm axis and spectra grid inspect_MRSI_spectra displays.
overlay_image_data_on_T1Display T1, resampled data, and overlay images side by side with a slice slider.
overlay_nifti_data_on_T1Resample a data NIfTI into T1 space and overlay it on the T1 image.
overlay_voxel_on_T1Overlay one or more voxels (and optionally MRSI data) on a T1 slice.

display_images

plotting.images.display_images(
    images,
    titles=None,
    fig_title='',
    cmap=None,
    imshow_kws=None,
    colorbar=False,
    colorbar_kws=None,
    fig_kws=None,
    vmin=None,
    vmax=None,
    v_percentile=1.0,
    zeros_as_nan=True,
    zooms=None,
    panel_height=None,
    grid_max_height=None,
    **kwargs,
)

Display a grid of 2D/3D/4D images, with a slice slider for 3D/4D input.

The panels are rendered straight to images at the data’s own resolution and handed to an interactive widget that draws the titles and colorbar around them as HTML; no matplotlib Figure is involved, which is why nothing is returned.

Parameters

NameTypeDescriptionDefault
imagesndarray or listImage data (2D, 3D, or 4D) or a list of arrays to stack along a new last axis.required
titleslist[str]Titles for each image, by default None.None
fig_titlestrOverall figure title, by default “”.''
cmapstrColormap to use. Defaults to rcParams["image.cmap"].None
imshow_kwsdictAccepted and ignored: there is no imshow call left to forward them to. Kept so existing call sites keep working.None
colorbarboolWhether to display a colorbar, by default False.False
colorbar_kwsdictOnly the "mode" key is read, either "single" (one colorbar for the grid) or "each" (one per panel, autoscaled to that panel and slice). Remaining keys are ignored -- the colorbar is HTML now, not a matplotlib artist.None
fig_kwsdictAccepted and ignored: there is no Figure left to configure. Kept so existing call sites keep working.None
vminfloatLower display bound. Estimated from the data if omitted.None
vmaxfloatUpper display bound. Estimated from the data if omitted.None
v_percentilefloatPercentile used to estimate vmin/vmax when not given, by default 1.0.1.0
zeros_as_nanboolIf True, zeros are treated as NaN: kept out of the vmin/vmax estimate so the background cannot drag the scaling down, and rendered transparent rather than as the colormap’s low end. By default True.True
zoomstuple[float, float]Physical (row, col) voxel edge lengths of the displayed slice, e.g. from utils.nifti.get_display_zooms. When given, panels are rendered with an aspect ratio that matches real anatomy instead of one square pixel per voxel; the through-plane spacing is irrelevant since only one 2D slice is ever on screen at a time. Defaults to the pixel-count aspect ratio (square voxels) when omitted.None
panel_heightstr or floatHow tall a single panel may grow, as a CSS length ("30rem", "400px") or a bare number read as rem. The compact default suits a row of low-resolution panels; raise it to read a high-resolution anatomical series. Defaults to rcParams["grid.panel_height"].None
grid_max_heightstr or floatHow tall the panel box may grow before it scrolls, same units. Worth raising alongside panel_height for a tall single-column view. Defaults to rcParams["grid.max_height"].None
**kwargsAccepted and ignored: axis parameters such as aspect, xlabel or xticks have no Axes to apply to. Kept so existing call sites keep working.{}

Returns

NameTypeDescription
NoneThe grid is displayed as a widget. For a single-slice input the widget simply has no slider.

display_nifti

plotting.images.display_nifti(nii, orientation=None, **kwargs)

Orient a NIfTI image and display it via display_images.

Parameters

NameTypeDescriptionDefault
niinibabel.spatialimages.SpatialImage or GESeries.NiiBaseThe NIfTI image (or wrapper) to display.required
orientationtuple[str, str, str]Target axis orientation codes, by default None.None
**kwargsAdditional keyword arguments forwarded to display_images.{}

Returns

NameTypeDescription
NoneSee display_images -- the image grid is displayed, not returned.

draw_voxel_overlays_on_ax

plotting.images.draw_voxel_overlays_on_ax(
    ax,
    voxel_coords,
    mrsi_to_display_affine,
    voxel_kwargs=None,
)

Draw voxel outlines on an axis.

mrsi_to_display_affine must map MRSI voxel indices to display pixel coordinates (row, col) as produced by orient_nifti. Use utils.nifti.get_display_affine to obtain the display affine for the T1, then compute mrsi_to_display = inv(display_affine) @ MRSI.RAW_exp.nii.affine.

The voxel’s four in-plane corners (voxel index +/- 0.5 along axes 0 and 1) are projected through the full affine, so this is correct for display affines that transpose or rotate the axes -- reading the affine diagonal is not, because get_display_affine bakes an axis transpose into an anti-diagonal affine.

fast_bounds

plotting.images.fast_bounds(
    data,
    max_target_samples=20000,
    p_lower=1.0,
    p_upper=99.0,
    exclude_zeros=False,
    max_discrete_levels=16,
)

Quickly estimate lower/upper display bounds by sampling a subset of the data.

The sample is drawn before the data is filtered, so the cost scales with max_target_samples rather than with the size of data. Continuous data is then summarised by percentiles; discrete data -- a label map or a binary mask -- by its exact min/max, since percentiles collapse onto a single level once the background outweighs the labels.

Parameters

NameTypeDescriptionDefault
datandarrayThe input data array from which to estimate the bounds.required
max_target_samplesintThe number of voxels drawn for the estimate. Defaults to 20000, which keeps the percentile standard error well below display resolution.20000
p_lowerfloatThe lower percentile to calculate. Defaults to 1.0 (the 1st percentile).1.0
p_upperfloatThe upper percentile to calculate. Defaults to 99.0 (the 99th percentile).99.0
exclude_zerosboolIf True, drop exact zeros before taking the percentiles. Background voxels are usually exactly 0 and would otherwise dominate the lower percentile and flatten the contrast of the anatomy itself. Ignored when the sample is all zeros -- a warning is logged and the zeros are kept so the bounds stay finite. Defaults to False.False
max_discrete_levelsintArrays whose sample holds at most this many distinct integer-valued levels are read as label maps and bounded by min/max instead of by percentiles. Defaults to 16.16

Returns

NameTypeDescription
tuple[float, float]The estimated lower and upper bounds for visualization, always with upper > lower.

get_voxel_visible_slice_range

plotting.images.get_voxel_visible_slice_range(
    voxel_coord,
    mrsi_to_display_affine,
    n_slices=None,
)

Return inclusive third-dimension slice range where a voxel is visible.

inspect_MRSI_spectra

plotting.images.inspect_MRSI_spectra(
    T1,
    MRSI,
    blocky=True,
    magnitude=False,
    autophase=True,
)

Display an interactive widget to inspect MRSI spectra over a T1 image.

Shows the T1 image with an MRSI overlay and a spectrum plot; clicking, the keyboard arrows, or the slice slider update the selected voxel and its spectrum. All interaction runs client-side (no Python kernel needed after the widget is displayed): every anatomical slice is pre-rendered, and every voxel’s spectrum is precomputed into a single buffer embedded in the widget.

Parameters

NameTypeDescriptionDefault
T1GESeries.MRISeriesThe T1-weighted anatomical series.required
MRSIGESeries.MRSISeriesThe MRSI series to inspect.required
blockyboolIf True, resample the raw (blocky) MRSI grid rather than the interpolated NIfTI, by default True.True
magnitudeboolIf True, display the magnitude spectrum, by default False.False
autophaseboolIf True (and magnitude is False), phase each voxel independently before display, by default True. See mrsi_spectra_for_display for why this is done per voxel rather than through a single global fit.True

mrsi_spectra_for_display

plotting.images.mrsi_spectra_for_display(
    MRSI,
    *,
    magnitude=False,
    autophase=True,
)

Build the exact ppm axis and spectra grid inspect_MRSI_spectra displays.

Split out of the widget so the displayed numbers can be inspected directly — the inspector ships precisely this array, so plotting spectra[x, y, z] against ppm reproduces a voxel’s panel exactly:

ppm, spectra = mrsi_spectra_for_display(mrsi) # doctest: +SKIP plt.plot(ppm, spectra[8, 8, 8]) # doctest: +SKIP

Parameters

NameTypeDescriptionDefault
MRSIGESeries.MRSISeriesThe MRSI series to read spectra from.required
magnitudeboolIf True, return the magnitude spectrum, by default False.False
autophaseboolIf True (and magnitude is False), phase each voxel independently, by default True.True

Returns

NameTypeDescription
ppmndarray1-D ppm axis, spanning the full acquired sweep.
spectrandarrayReal-valued grid indexed [x, y, mrsi_slice, point], matching the voxel coordinates the widget’s picker reports.

overlay_image_data_on_T1

plotting.images.overlay_image_data_on_T1(
    t1_images,
    data_images=None,
    mask=None,
    mask_contour=None,
    only_overlay=False,
    mask_kwargs=None,
    engine=None,
    ax=None,
    **kwargs,
)

Display T1, resampled data, and overlay images side by side with a slice slider.

Parameters

NameTypeDescriptionDefault
t1_imagesndarrayT1-weighted anatomical image data.required
data_imagesndarrayData image, resampled into T1 space, to overlay. Required unless ax is given for a T1-only draw.None
maskndarrayBoolean mask applied to the overlay data, by default None.None
mask_contourndarray or boolMask (or True to reuse mask) whose contour is drawn on the overlay axis. Matplotlib engine only -- the raster engine has no cheap contour equivalent and warns and ignores it.None
only_overlayboolIf True, only show the overlay axis instead of T1, data, and overlay side by side, by default False.False
mask_kwargsdictKeyword arguments customizing the mask contour’s appearance.None
engine('raster', 'matplotlib')Rendering path. Defaults to "raster" (fast, no Figure) unless ax is given, which forces matplotlib -- there is no client-side Axes for a raster widget to draw into. If both are given, ax wins and a mismatched engine="raster" is ignored with a warning."raster"
axmatplotlib.axes.AxesDraw a single overlay panel onto this axis instead of displaying the T1/data/overlay widget. Implies the matplotlib engine.None
**kwargsAdditional keyword arguments forwarded to the resolved rendering path. The raster engine also takes panel_height and grid_max_height, which size the widget exactly as they do in display_images.{}

Returns

NameTypeDescription
tuple[Figure, list[Axes]] or tuple[list[AxesImage], QuadContourSet | None] or Noneax given: the plotted images and contours. engine="matplotlib" with no ax: (Figure, axes) for single-slice input, None (widget displayed) for multi-slice. Raster engine (default): always None (widget displayed), single-slice included.

overlay_nifti_data_on_T1

plotting.images.overlay_nifti_data_on_T1(
    t1_nii,
    data_nii,
    orientation=None,
    display_plane=None,
    resample_kwargs=None,
    mask=None,
    **kwargs,
)

Resample a data NIfTI into T1 space and overlay it on the T1 image.

Parameters

NameTypeDescriptionDefault
t1_niinibabel.spatialimages.SpatialImageAnatomical T1 NIfTI image to overlay onto.required
data_niinibabel.spatialimages.SpatialImageData NIfTI image to resample and overlay.required
orientationtuple[str, str, str]Target axis orientation codes, by default None.None
display_planeutils.nifti.DISPLAY_PLANESAnatomical plane to display, by default None.None
resample_kwargsdictExtra keyword arguments passed to resample_and_orient_nifti.None
maskndarray or GESeries.NiiBaseBoolean mask applied to the data before or after resampling, depending on whether its shape matches the data or the T1 image.None
**kwargsAdditional keyword arguments forwarded to overlay_image_data_on_T1.{}

Returns

NameTypeDescription
tuple[Figure, list[Axes]] or NoneSee overlay_image_data_on_T1.

overlay_voxel_on_T1

plotting.images.overlay_voxel_on_T1(
    t1,
    MRSI,
    voxel_coords,
    ax=None,
    figsize=(6, 6),
    **kwargs,
)

Overlay one or more voxels (and optionally MRSI data) on a T1 slice.

Displays a slice of a T1-weighted MRI image, overlays voxel(s) at the specified coordinates, and optionally overlays MRSI data resampled into T1 space. If ax is omitted, creates its own figure and axes.

Parameters

NameTypeDescriptionDefault
t1GESeries.MRISeriesThe T1-weighted MRI series containing the anatomical image data.required
MRSIGESeries.MRSISeriesThe MRSI series containing the spectroscopic imaging data.required
voxel_coordstuple[int, int, int] or ndarray or list[tuple[int, int, int]]The coordinates of the voxel(s) in MRSI space. If a list is given, all voxels must share the same z-coordinate.required
axmatplotlib.axes.AxesThe axis on which to plot the image and overlays. If None, a new figure and axis are created.None
figsizetuple[int, int]The size of the figure in inches, used only when ax is None. Defaults to (6, 6).(6, 6)
**kwargsUnpack[VoxelOverlayParams]show_overlay : bool, optional Whether to overlay the MRSI data on the T1 image. Defaults to True. scale_overlay : bool, optional Whether to scale the MRSI data to [0, 1] for better visualization when overlaid. Defaults to True. title : str, optional Title for the plot. Defaults to one naming the anatomical slice index. voxel_kwargs : dict or list[dict], optional Keyword arguments customizing the voxel rectangle(s)’ appearance. If a list, it must match the number of voxels. Defaults to None. image_kwargs : dict, optional Keyword arguments customizing the T1 image’s appearance. overlay_kwargs : dict, optional Keyword arguments customizing the MRSI overlay’s appearance.{}

Returns

NameTypeDescription
tuple[matplotlib.figure.Figure, matplotlib.axes.Axes] or matplotlib.axes.AxesThe created (fig, ax) if ax was None, otherwise the axis with the plotted image and overlays.

Notes

The MRSI data is resampled to T1 space using the provided affine transformations, then scaled to [0, 1] if scale_overlay is True. The voxel rectangle(s) are drawn at the specified coordinates, adjusted to align with the anatomical space.