upxo.viz.ebsdviz module

EBSD visualisation helpers for UPXO.

All functions accept an upxo.interfaces.defdap.ebsd_reader.EBSDReader instance (or plain NumPy arrays where noted) and produce Matplotlib figures.

Usage

import upxo.viz.ebsdviz as ebsdviz

upxo.viz.ebsdviz.plot_grain_labels(rdr, show_boundaries: bool = True, boundary_color=(0, 0, 0), cmap: str = 'nipy_spectral', figsize: tuple = (7, 6), dpi: int = 100, title: str = 'Grain label field', ax=None)[source]

Plot the grain label field (lfi_ebsd) with optional boundary overlay.

Parameters:
  • rdr (EBSDReader) – Loaded EBSD reader with lfi_ebsd populated.

  • show_boundaries (bool) – Whether to overlay grain boundaries in black.

  • boundary_color (tuple) – RGB tuple for boundary colour (values 0–1).

  • cmap (str) – Matplotlib colormap for grain IDs.

  • figsize (tuple, int) – Figure size and resolution.

  • dpi (tuple, int) – Figure size and resolution.

  • title (str) – Axes title.

  • ax (matplotlib.axes.Axes or None) – If provided, draw onto this axes; otherwise create a new figure.

Return type:

fig, ax

upxo.viz.ebsdviz.plot_euler_maps(rdr, show_boundaries: bool = True, boundary_color=(0, 0, 0), cmaps=('hsv', 'viridis', 'hsv'), figsize: tuple = (15, 5), dpi: int = 100, suptitle: str = 'Bunge Euler angle maps')[source]

Plot phi1, Phi, phi2 Euler maps side-by-side.

Parameters:
  • rdr (EBSDReader) – Loaded EBSD reader with euler_ebsd and lfi_ebsd populated.

  • show_boundaries (bool) – Overlay grain boundaries on every panel.

  • cmaps (tuple of str) – One colormap per channel (phi1, Phi, phi2).

  • figsize (tuple, int) – Figure size and resolution.

  • dpi (tuple, int) – Figure size and resolution.

Return type:

fig, axes

upxo.viz.ebsdviz.build_ipf_rgb(lfi: numpy.ndarray, quats_dict: dict, sample_direction=(0.0, 0.0, 1.0), grey: tuple = (0.75, 0.75, 0.75)) numpy.ndarray[source]

Build a pixel-level IPF RGB image from an integer label field and a grain-quaternion mapping.

Parameters:
  • lfi (ndarray (ny, nx), int) – Pixel label field; each value is a grain ID.

  • quats_dict (dict {int gid -> ndarray (4,)}) – Quaternion (w, x, y, z) for each oriented grain.

  • sample_direction (array-like (3,)) – Sample reference direction for IPF colouring. Default [001] (ND).

  • grey (tuple of 3 floats) – RGB colour for pixels whose grain has no assigned orientation.

Returns:

rgb

Return type:

ndarray (ny, nx, 3), float32 in [0, 1]

upxo.viz.ebsdviz.plot_grain_size_histogram(rdr, figsize: tuple = (7, 4), dpi: int = 100, bins: int = 40, color: str = 'steelblue')[source]

Plot a grain area histogram in physical units (µm²).

Parameters:

rdr (EBSDReader) – Loaded EBSD reader with lfi_ebsd and step_size populated.

Return type:

fig, ax

upxo.viz.ebsdviz.plot_grain_structure_with_boundaries(rdr, show_euler_panel: bool = True, euler_channel: int = 0, boundary_color=(0, 0, 0), figsize: tuple = (16, 7), dpi: int = 100, suptitle: str = 'Grain structure with grain boundaries')[source]

Two-panel figure: grain label map + Euler background, both with boundaries.

Parameters:
  • rdr (EBSDReader) – Loaded EBSD reader.

  • show_euler_panel (bool) – If False, only the grain-label panel is shown (single axes).

  • euler_channel (int) – Which Euler channel (0=phi1, 1=Phi, 2=phi2) to use as orientation background in the right panel.

  • boundary_color (tuple) – RGB boundary overlay colour (values 0–1).

  • figsize (tuple, int) – Figure size and resolution.

  • dpi (tuple, int) – Figure size and resolution.

  • suptitle (str) – Overall figure title.

Return type:

fig, axes (axes is a single Axes if show_euler_panel=False)

upxo.viz.ebsdviz.plot_mdf(mdf: dict, peaks: dict, figsize: tuple[float, float] = (9, 4), angle_max: float = 65.0) tuple[source]

Plot a grain-boundary MDF histogram with KDE overlay, CSL reference lines, and auto-detected peak annotations.

Parameters:
  • mdf (dict) – Output of crystal_orientation.compute_mdf_from_quats().

  • peaks (dict) – Output of crystal_orientation.detect_mdf_peaks().

  • figsize ((float, float)) – Figure size. Default (9, 4).

  • angle_max (float) – Upper x-axis limit in degrees. Default 65.

Return type:

fig, ax

upxo.viz.ebsdviz.plot_mdf_selected(mdf: dict, peaks: dict, selected_peaks: dict, figsize: tuple[float, float] = (9, 4), angle_max: float = 65.0) tuple[source]

Replot the MDF histogram + KDE with only the user-selected peaks highlighted in colour (unselected bins are greyed out).

Parameters:
  • mdf (dict) – Output of crystal_orientation.compute_mdf_from_quats().

  • peaks (dict) – Output of crystal_orientation.detect_mdf_peaks().

  • selected_peaks (dict) – Output of mdf_peak_selector() after user confirmation. Keys: 'angles' and 'indices'.

  • figsize ((float, float))

  • angle_max (float)

Return type:

fig, ax

upxo.viz.ebsdviz.plot_csl_grain_map(lfi: numpy.ndarray, csl_grains: dict, figsize: tuple[float, float] = (10, 5), dpi: int = 130, alpha_bg: float = 0.15, suptitle: str | None = None) tuple[source]

Colour-code the grain label field by CSL boundary participation.

Each CSL type present in csl_grains gets its own colour. Grains that touch boundaries of more than one CSL type have blended colours. Non-CSL grains are shown in semi-transparent light grey.

Parameters:
  • lfi (ndarray, shape (ny, nx)) – Integer grain label field (positive = grain ID, ≤0 = unindexed).

  • csl_grains (dict) – Output of crystal_orientation.segregate_csl_pairs(). Keys are CSL labels; each value must have 'grains_all', 'n_pairs', and 'n_grains'.

  • figsize – Standard figure parameters.

  • dpi – Standard figure parameters.

  • alpha_bg – Standard figure parameters.

  • suptitle – Standard figure parameters.

Return type:

fig, ax

upxo.viz.ebsdviz.print_parent_grain_summary(parent_info: dict, csl_grains: dict) None[source]

Print a formatted table of parent / twin / intermediate grain counts for each CSL type.

Parameters:
  • parent_info (dict) – Output of crystal_orientation.identify_parent_grains().

  • csl_grains (dict) – Output of crystal_orientation.segregate_csl_pairs() — used to retrieve the number of pairs per CSL label.

upxo.viz.ebsdviz.plot_parent_grain_summary(parent_info: dict, figsize: tuple[float, float] = (8, 4), dpi: int = 120, title: str = 'Parent / twin / intermediate grain counts per CSL type', bar_width: float = 0.25, colors: tuple[str, str, str] = ('steelblue', 'coral', 'mediumseagreen')) tuple[source]

Grouped bar chart of pure-parent, pure-twin, and intermediate grain counts for each CSL type.

Parameters:
  • parent_info (dict) – Output of crystal_orientation.identify_parent_grains().

  • figsize – Standard figure parameters.

  • dpi – Standard figure parameters.

  • title – Standard figure parameters.

  • bar_width (float) – Width of each bar group.

  • colors (tuple of str) – Three colours for (pure parents, pure twins, intermediates).

Return type:

fig, ax

upxo.viz.ebsdviz.plot_parent_twin_map(lfi: numpy.ndarray, parent_info: dict, figsize: tuple[float, float] = (10, 5), dpi: int = 130, alpha_bg: float = 0.12, colors: dict | None = None, suptitle: str | None = None) tuple[source]

Colour-code the grain label field by parent / twin / intermediate role for each CSL type present in parent_info.

One subplot is produced per CSL type. Within each subplot:

  • Pure parents – solid blue (default)

  • Pure twins – solid coral / red

  • Intermediates – solid green

  • Non-role grains – semi-transparent light grey

Parameters:
  • lfi (ndarray, shape (ny, nx)) – Integer grain label field.

  • parent_info (dict) – Output of crystal_orientation.identify_parent_grains().

  • figsize – Figure dimensions per subplot (total width scaled by n_csl).

  • dpi – Figure dimensions per subplot (total width scaled by n_csl).

  • alpha_bg (float) – Opacity of non-role background grains.

  • colors (dict, optional) – Override role colours. Keys: 'pure_parent', 'pure_twin', 'intermediate'. Values: any Matplotlib colour spec.

  • suptitle (str, optional) – Figure-level title.

Return type:

fig, axes

upxo.viz.ebsdviz.plot_combined_parent_twin_map(lfi: numpy.ndarray, parent_info: dict, figsize: tuple[float, float] = (10, 5), dpi: int = 130, alpha_bg: float = 0.1, color_parent: str = '#4878CF', color_twin: str = '#D65F5F', color_intermediate: str = '#59A14F', suptitle: str | None = 'Pure-parent and pure-twin grains (all CSL types combined)') tuple[source]

Single map showing pure-parent, pure-twin and intermediate grains aggregated across all CSL types in parent_info.

A grain that is a pure-parent in any CSL type → coloured as parent. A grain that is a pure-twin in any CSL type → coloured as twin. A grain that is intermediate in any CSL type → coloured as intermediate. Priority when a grain appears in multiple roles: intermediate > parent > twin.

Parameters:
  • lfi (ndarray, shape (ny, nx)) – Integer grain label field.

  • parent_info (dict) – Output of crystal_orientation.identify_parent_grains().

  • figsize – Figure size and resolution.

  • dpi – Figure size and resolution.

  • alpha_bg (float) – Opacity of non-role grains.

  • color_parent (str) – Matplotlib colour specs for each role.

  • color_twin (str) – Matplotlib colour specs for each role.

  • color_intermediate (str) – Matplotlib colour specs for each role.

  • suptitle (str or None) – Figure title.

Return type:

fig, ax

upxo.viz.ebsdviz.plot_grain_role_property_stats(lfi: numpy.ndarray, parent_info: dict, prop: dict, neigh_gid: dict, selected_props: list | None = None, selected_groups: list | None = None, step_size: float = 1.0, bins: int = 40, bw_method: str = 'scott', peak_prominence: float = 0.01, figsize_per: tuple[float, float] = (5, 4), dpi: int = 110, suptitle: str = 'Grain morphological & topological statistics by role', ncols: int | None = None, fontsize: float = 9.0) tuple[source]

For each selected property, plot overlaid histograms + KDE + detected peaks for each selected grain-role group (pure parents, pure twins, intermediates, non-role). Min / max / mean / std are embedded in the legend labels.

Parameters:
  • lfi (ndarray, shape (ny, nx)) – Integer grain label field.

  • parent_info (dict) – Output of identify_parent_grains().

  • prop (dict) – Per-grain property dict (grain_id → dict) as from prop_ebsd. Expected keys: 'area', 'aspect_ratio', 'perimeter', 'solidity'.

  • neigh_gid (dict) – Neighbour-grain dict (grain_id → list of neighbour IDs) as from neigh_gid_ebsd. Used to derive n_neighbours.

  • selected_props (list of str, optional) – Subset of ['area', 'aspect_ratio', 'perimeter', 'solidity', 'n_neighbours']. Defaults to all five.

  • selected_groups (list of str, optional) – Subset of ['pure_parents', 'pure_twins', 'intermediates', 'non_role']. Defaults to all four.

  • step_size (float) – EBSD step size (µm). Multiplied into area (px² → µm²) and perimeter (px → µm) values.

  • bins (int) – Number of histogram bins.

  • bw_method (str) – Bandwidth selector passed to scipy.stats.gaussian_kde.

  • peak_prominence (float) – Fraction of KDE max used as minimum prominence for peak annotation.

  • figsize_per (tuple) – (width, height) in inches for each subplot.

  • dpi (int) – Figure resolution.

  • suptitle (str) – Figure-level title.

  • ncols (int or None) – Number of columns in the subplot grid. None (default) places all subplots in a single row. E.g. ncols=2 gives a 2-column grid; ncols=1 gives a single column.

  • fontsize (float) – Base font size in points. Axis labels and titles use this size; tick labels use fontsize - 2; legend text uses fontsize - 2; peak annotations use fontsize - 3; the figure suptitle uses fontsize + 1. Default 9.0.

Return type:

fig, axes

upxo.viz.ebsdviz.print_grain_role_ratios(ratios: dict) None[source]

Print a formatted table of grain-role counts and ratios produced by crystal_orientation.compute_grain_role_ratios().

Parameters:

ratios (dict) – Output of compute_grain_role_ratios().

upxo.viz.ebsdviz.plot_grain_role_map(lfi: numpy.ndarray, role_sets: dict, figsize: tuple[float, float] = (10, 5), dpi: int = 130, alpha_bg: float = 0.1, color_parent: str = '#4878CF', color_twin: str = '#D65F5F', color_intermediate: str = '#59A14F', suptitle: str | None = None) tuple[source]

Plot a grain role map from pre-computed role sets (output of crystal_orientation.assign_grain_roles_by_ratio() or crystal_orientation.compute_grain_role_ratios()).

Parameters:
  • lfi (ndarray, shape (ny, nx)) – Integer grain label field.

  • role_sets (dict) – Dict with keys 'pure_parents', 'pure_twins', 'intermediates', 'non_role' — each value either a set of grain IDs or a sub-dict with a 'grain_ids' key (as returned by assign_grain_roles_by_ratio()).

  • figsize – Figure parameters.

  • dpi – Figure parameters.

  • alpha_bg – Figure parameters.

  • color_parent (str) – Matplotlib colour specs for each role.

  • color_twin (str) – Matplotlib colour specs for each role.

  • color_intermediate (str) – Matplotlib colour specs for each role.

  • suptitle (str or None) – Figure title.

Return type:

fig, ax

upxo.viz.ebsdviz.plot_twin_introduction_map(lfi_before: numpy.ndarray, twin_result: dict, figsize: tuple = (14, 5), dpi: int = 130, color_parent: str = '#4878CF', color_twin: str = '#D65F5F', color_other: str = '#CCCCCC', alpha_other: float = 0.3, show_cut_lines: bool = True, suptitle=None) tuple[source]

Side-by-side comparison of the grain label field before and after twin introduction, with cut-lines overlaid on the “after” panel.

Parameters:
  • lfi_before (ndarray, shape (ny, nx)) – Grain label field before twin introduction.

  • twin_result (dict) – Output of crystal_orientation.introduce_twins_by_csl().

  • figsize (tuple) – Total figure size (width, height).

  • dpi (int) – Figure resolution.

  • color_parent (str) – Colour for parent grains.

  • color_twin (str) – Colour for newly introduced twin grains.

  • color_other (str) – Colour for all other grains.

  • alpha_other (float) – Opacity for other grains.

  • show_cut_lines (bool) – If True, overlay the Sline2d cut-lines on the “after” panel.

  • suptitle (str or None) – Figure-level title.

Return type:

fig, axes

upxo.viz.ebsdviz.plot_twin_thickness_stats(stats: dict, bins: int = 30, figsize: tuple = (7, 4), dpi: int = 120, color: str = 'steelblue', title: str | None = None) tuple[source]

Plot a histogram of twin lamella thickness from the dict returned by compute_twin_thickness_stats.

Parameters:
  • stats (dict) – Output of compute_twin_thickness_stats.

  • bins (int) – Number of histogram bins.

  • figsize ((width, height))

  • dpi (int)

  • color (str) – Bar fill colour.

  • title (str or None) – Custom figure title; auto-generated when None.

Return type:

fig, ax

upxo.viz.ebsdviz.plot_grain_area_comparison(scale_result: dict, bins: int = 50, pct_clip: float = 97.0, figsize: tuple = (8, 4), dpi: int = 120, color_ebsd: str = 'steelblue', color_sim: str = 'tomato') tuple[source]

Plot overlapping grain-area histograms for the EBSD target and the scaled synthetic structure.

Parameters:
  • scale_result (dict) – Output of compute_scale_factor_grain_size. Must contain 'areas_ebsd_um2', 'areas_sim_um2', 'mean_area_ebsd_um2', 'scale_factor', and 'mean_area_sim_um2'.

  • bins (int) – Number of histogram bins.

  • pct_clip (float) – Upper percentile used to clip the x-axis range (avoids giant outlier grains dominating the axis).

  • figsize (figure size and resolution.)

  • dpi (figure size and resolution.)

  • color_ebsd (bar fill colours.)

  • color_sim (bar fill colours.)

Return type:

fig, ax