pyfli.data_vnp.model_selector_plotter#

Figures for per-pixel mono- vs bi-exponential model selection.

Functions

_sans_font()

Classes

ModelSelectorPlotter([selector, save_dir, ...])

Publication figures (Nature Methods style) driven by mono/bi model selection.

class ModelSelectorPlotter(selector=None, save_dir=None, b_bool_mask=None, fit='CPU_MLE_poisson', maps=None, model='selector', fallback_model='mono', split_min_frac=0.05, other_color='transparent', show_other_key=True, pixel_size=None, scale_bar=(5, 'mm'), clip_pct=(2, 98), tau_bound=12.5, v_ranges=None, crop_to_roi=True, swap_xy=True, bg_color='grey', tau_box=True)[source]#

Bases: object

Publication figures (Nature Methods style) driven by mono/bi model selection.

model chooses which model every ROI pixel is shown with:

  • "selector" (default): follow ModelSelector. Draws the split figures when at least split_min_frac of ROI pixels are bi-justified, otherwise the whole-ROI mono figure. Box plots use the selector’s pixel classes.

  • "mono": every ROI pixel is mono-exponential. Map figure of photon counts and τ; box plot of τ over the whole ROI. Only the mono fit is needed.

  • "bi": every ROI pixel is bi-exponential. Map figure of photon counts, τ1, τ2, τm, FRET fraction and FRET efficiency; box plots of those over the whole ROI. Only the bi fit is needed.

  • "split": like "selector" but always draws the split figures. Each figure shows only its own pixel class (mono: classes 1 and 4; bi: class 2), other ROI pixels are drawn in other_color, and the mono figure gains an unmasked photon-count panel.

Parameters:
  • selector (ModelSelector | None) – Selector that has already run compare/compare_from_dir. Needed for "selector" and "split"; not used by "mono" or "bi".

  • save_dir (str | None) – Directory holding {fit}_{mono|bi}-exponential.npy and receiving the saved figures. None disables saving (then maps must be given).

  • b_bool_mask (np.ndarray | None) – ROI mask; defaults to selector.roi.

  • fit (str) – File prefix of the saved fit, e.g. "CPU_MLE_poisson" or "CPU_NLSF_least_squares".

  • maps (dict | None) – Optional {"mono": maps, "bi": maps} result maps used instead of loading from save_dir.

  • model (str) – "selector" (default), "mono", "bi" or "split"; see above.

  • fallback_model (str) – Model used by "selector" when no selector result is available ("mono" or "bi").

  • split_min_frac (float) – Bi-justified fraction needed for "selector" to draw the split figures.

  • other_color (str) – Colour of ROI pixels in the other class in split mode; "transparent" leaves them blank.

  • show_other_key (bool) – Draw a small key explaining the other_color pixels.

  • pixel_size (float | None) – Physical pixel size; None draws no scale bar.

  • scale_bar (tuple[float, str]) – (length, unit) of the scale bar, used only when pixel_size is set.

  • clip_pct (tuple[float, float]) – Percentiles for robust colour limits from the shown pixels.

  • tau_bound (float) – Lifetime fit bound in ns; values at or above it are ignored for colour limits.

  • v_ranges (dict | None) – Manual colour-limit overrides, e.g. {"tau_map": (0.5, 1.5)}.

  • crop_to_roi (bool) – Crop map panels to the ROI bounding box.

  • swap_xy (bool) – Transpose every map.

  • bg_color (str) – Colour of pixels outside the ROI.

  • tau_box (bool) – Add a τ box-plot panel to the mono-exponential map figure.

PANELS: ClassVar[dict[str, list[tuple[str, str, str, Any, float]]]] = {'bi': [('photon_count_map', 'Photon counts', 'Counts ($\\times10^{3}$)', 'magma', 0.001), ('tau1_map', '$\\tau_1$', '$\\tau_1$ (ns)', <matplotlib.colors.LinearSegmentedColormap object>, 1), ('tau2_map', '$\\tau_2$', '$\\tau_2$ (ns)', <matplotlib.colors.LinearSegmentedColormap object>, 1), ('tau_mean_map', '$\\tau_\\mathrm{m}$', '$\\tau_\\mathrm{m}$ (ns)', <matplotlib.colors.LinearSegmentedColormap object>, 1), ('alpha1_map', 'FRET fraction', '$f_\\mathrm{D}$ (%)', <matplotlib.colors.LinearSegmentedColormap object>, 100), ('fret_efficiency_map', 'FRET efficiency', '$E$ (%)', <matplotlib.colors.LinearSegmentedColormap object>, 100)], 'mono': [('photon_count_map', 'Photon counts', 'Counts ($\\times10^{3}$)', 'magma', 0.001), ('tau_map', 'Lifetime $\\tau$', '$\\tau$ (ns)', <matplotlib.colors.LinearSegmentedColormap object>, 1)], 'mono_split': [('photon_count_map', 'Photon counts (all pixels)', 'Counts ($\\times10^{3}$)', 'magma', 0.001), ('photon_count_map', 'Photon counts (mono pixels)', 'Counts ($\\times10^{3}$)', 'magma', 0.001), ('tau_map', 'Lifetime $\\tau$', '$\\tau$ (ns)', <matplotlib.colors.LinearSegmentedColormap object>, 1)]}#
LAYOUT: ClassVar[dict[str, tuple[int, int, float]]] = {'bi': (2, 3, 180), 'mono': (1, 2, 120), 'mono_split': (1, 3, 180)}#
BOX_COLORS: ClassVar[dict[str, str]] = {'eff': '#E69F00', 'frac': '#CC79A7', 'tau': '#0072B2', 'tau1': '#D55E00', 'tau2': '#0072B2', 'taum': '#009E73'}#
MONO_CLASSES: ClassVar[tuple[int, ...]] = (1, 4)#
BI_CLASSES: ClassVar[tuple[int, ...]] = (2,)#
MODELS: ClassVar[tuple[str, ...]] = ('selector', 'mono', 'bi', 'split')#
property selection: dict[str, Any] | None#

Model-selection result for label, or None if unavailable.

class_masks()[source]#

Mono and bi pixel masks from the selector’s class map.

Returns:

(mono_px, bi_px): mono adequate (classes 1, 4) and bi justified with parameters inside the fit limits (class 2).

Return type:

tuple[np.ndarray, np.ndarray]

load_maps(model)[source]#

Result maps of the model ("mono" or "bi") fit.

Parameters:

model (str) – "mono" or "bi".

Returns:

The results["maps"] dictionary of the saved fit.

Return type:

dict

map_rc()[source]#

Matplotlib rcParams used for the map figures.

Return type:

dict[str, Any]

box_rc()[source]#

Matplotlib rcParams used for the box-plot figure.

Return type:

dict[str, Any]

draw_fli_figure(model, show_mask=None, other_label=None)[source]#

Draw the model map panels.

Parameters:
  • model (str) – "mono" or "bi".

  • show_mask (np.ndarray | None) – Pixels to colour; other ROI pixels get other_color. None shows the whole ROI.

  • other_label (str | None) – Description of the masked-out pixels, used in the key.

Returns:

The drawn figure.

Return type:

matplotlib.figure.Figure

resolve_model()[source]#

Resolve model to "split", "mono" or "bi".

Returns:

The figure model that plot_maps() will draw.

Return type:

str

plot_maps()[source]#

Draw the lifetime map figure(s) selected by model.

Returns:

{"mono": fig, "bi": fig} in split mode, otherwise {model: fig}.

Return type:

dict

box_stats()[source]#

Summary statistics of the box-plot parameters per pixel class.

Returns:

One row per parameter: panel, class, parameter, unit, n, median, Q1, Q3, mean and SD.

Return type:

pd.DataFrame

plot_boxplots(width_mm=88, height_mm=None, show_points=False, n_points=300, show_n=True, whis=1.5, seed=0)[source]#

Box plots of the fitted parameters, following model.

  • "selector" / "split": (a) τ of mono pixels, (b) τ1, τ2, τm of bi pixels, (c) FRET fraction and efficiency of bi pixels.

  • "mono": (a) τ of all ROI pixels.

  • "bi": (a) τ1, τ2, τm and (b) FRET fraction and efficiency of all ROI pixels.

The statistics are also saved as Fig_FLI_boxplots_{fit}[_mono|_bi]_stats.csv when save_dir is set.

Parameters:
  • width_mm (float) – Figure width in mm (Nature: 88 single column, 180 double column).

  • height_mm (float | None) – Figure height in mm; None scales 190 mm (three panels) to the number of panels.

  • show_points (bool) – Overlay a random subsample of pixels on each box.

  • n_points (int) – Points per box when show_points.

  • show_n (bool) – Print the pixel count under the panels.

  • whis (float) – Whisker length in IQR (Tukey); outliers are not drawn.

  • seed (int) – Random seed for the point subsample and jitter.

Returns:

The figure and the summary statistics table.

Return type:

tuple[matplotlib.figure.Figure, pd.DataFrame]