Show Command Internals

Implementation details for the image display command, including file loading, Plotly figure construction, and layout helpers.

Show Package

Show Command Package

This package implements the GONet_Wizard.commands.show CLI command, which renders one or more GONet files as Plotly image panels for interactive inspection.

The command is intentionally split into focused modules:

  • command defines the CLI CommandSpec and the cli_handler().

  • figure constructs the Plotly plotly.graph_objects.Figure used by the command.

  • layout provides deterministic layout policy (subplot geometry, aspect locking, and zoom-linking payloads).

  • io contains optional export helpers (e.g. writing the figure to PDF).

The CLI registry expects the command specification and handler to be importable from the package, so they are re-exported here.

Constants

COMMAND

The CLI command specification for show.

Functions

cli_handler

CLI handler that builds the figure and returns the HTML payload for display.

Command

Show Command

This module defines the CommandSpec for the show command and implements its CLI handler.

The show command renders one or more GONet files as a Plotly figure and returns an HTML document (as a string) intended to be displayed by the GUI layer (e.g. a PyWebView window).

Unlike earlier versions, we do not rely on Plotly updatemenus for zoom-link controls. Instead, we generate a small, custom HTML “chrome” (buttons + optional channel label) around the Plotly figure. This keeps the controls visually consistent with the rest of the GONet Wizard UI (via style.css) and gives deterministic control over layout, spacing, and styling that is hard to achieve with Plotly’s built-in menu widgets.

The returned HTML embeds the Plotly figure and a tiny script that maps button clicks to plotly.graph_objects.Figure.relayout() via Plotly.relayout(...). The page also contains explicit Save figure and Exit buttons used by the interactive window.

Constants

COMMAND

The CommandSpec for the show command.

Functions

cli_handler

CLI entry-point for show. Builds the figure and returns the HTML document.

_int_or_default

Helper to parse an integer CLI value with a safe fallback.

_resolve_channels

Resolves which channels should be displayed based on CLI flags.

GONet_Wizard.commands.show.command.cli_handler(args)[source]

Build and render the show output as a standalone HTML document.

The handler:

  1. Resolves input files and channel selection from CLI arguments.

  2. Builds a Plotly figure using build_show_figure().

  3. Registers an interactive session for the returned window.

  4. Computes “zoom linking” payloads and emits custom HTML buttons that call Plotly.relayout(graphDiv, payload).

  5. Returns the HTML string to the UI layer (PyWebView / GUI launcher) for display.

We generate the HTML here (instead of relying on Plotly updatemenus) because it provides deterministic control over the UI “chrome”:

  • Layout is stable across different grid shapes (single-channel grids vs per-file rows) and across different WebView implementations.

  • The UI is decoupled from Plotly’s menu rendering quirks and limitations.

The interactive window provides explicit Save figure and Exit buttons. Save figure opens a native OS save dialog, then closes the window and lets the backend rebuild and export the figure in the background while terminal feedback remains visible in the CLI or GUI fake terminal.

Parameters:

args (argparse.Namespace) – Parsed CLI arguments as created by COMMAND.

Return type:

Optional[str]

Returns:

str or None – A complete HTML document as a string. If your surrounding CLI framework supports “no UI output” paths, this may return None (currently unused).

Raises:

Figure Construction

Show Figure Builder

This module constructs the Plotly Figure used by the show command.

The design goal is deterministic sizing in a PyWebView context, where responsive HTML can otherwise cause row spacing and layout to “breathe” depending on the number of subplots. To keep the visual rhythm stable:

  • Figure width is derived from the PyWebView window width.

  • Figure height is derived from either: - one “row per file” sizing when plotting multiple channels, or - a compact grid sizing when plotting a single channel across multiple files.

  • Pixel spacing (row gaps, header bands, title offsets) is converted to paper coordinates (fractions) using the figure’s effective plot area.

This module also loads GONet files, prepares per-channel intensity bounds, and emits either:

Classes

_LoadedFile

Internal container for loaded file data and derived display bounds.

Functions

auto_vmin_vmax

Compute percentile-based display bounds for image-like arrays.

build_show_figure

Build the Figure for the show command.

_load_files

Load one or more files into a normalized internal representation.

_representative_hw

Pick a representative image height/width for sizing heuristics.

GONet_Wizard.commands.show.figure.auto_vmin_vmax(data, lower_percentile=0.5, upper_percentile=99.5)[source]

Compute robust display bounds for an image using percentiles.

Parameters:
  • data (numpy.ndarray) – Image-like array.

  • lower_percentile (float, optional) – Lower percentile used for vmin. Defaults to 0.5.

  • upper_percentile (float, optional) – Upper percentile used for vmax. Defaults to 99.5.

Return type:

tuple[float, float]

Returns:

tuple [float, float] – (vmin, vmax) suitable for Plotly zmin/zmax.

Notes

If percentile computation results in non-finite or degenerate bounds, this falls back to min/max of finite values and enforces vmax > vmin.

GONet_Wizard.commands.show.figure.build_show_figure(files, channels, *, lower_percentile=0.5, upper_percentile=99.5, window_width_px=1250, window_height_px=800, width_frac=0.95, row_height_frac=0.5)[source]

Build the Plotly figure for the show command.

Parameters:
  • files (collections.abc.Sequence [str or pathlib.Path]) – Input file paths.

  • channels (collections.abc.Sequence [str]) – Channel names to plot. If length is 1, a compact grid is used. If length is greater than 1, the figure uses one row per file and one column per channel.

  • lower_percentile (float, optional) – Lower percentile for display bounds.

  • upper_percentile (float, optional) – Upper percentile for display bounds.

  • window_width_px (int, optional) – Target UI window width in pixels (used for deterministic sizing).

  • window_height_px (int, optional) – Target UI window height in pixels (used for deterministic sizing).

  • width_frac (float, optional) – Fraction of the window width used for the figure width.

  • row_height_frac (float, optional) – Fraction of the window height used for each per-file row in the multi-channel layout.

Return type:

Figure

Returns:

plotly.graph_objects.Figure – Fully constructed and styled figure.

Raises:

ValueError – If channels is empty.

I/O Helpers

Show Export Utilities

This module provides export helpers for the show command, primarily for writing the interactive show figure to disk.

The show command renders interactive HTML for viewing in a UI window, but it also supports saving an artifact for sharing or archival. HTML export preserves the full interactive Plotly figure. Static exports are rendered with Matplotlib from the figure’s heatmap data so packaged desktop apps do not depend on Kaleido/Chrome being available at runtime.

Functions

save_figure_plotly

Export a Plotly figure to PDF/PNG/SVG/JPEG or self-contained HTML, automatically adding a default extension and avoiding overwrites by suffixing a counter.

GONet_Wizard.commands.show.io.save_figure_plotly(fig, save_path)[source]

Export a Plotly show figure, avoiding overwrites.

If save_path has no extension, .pdf is appended. Static extensions .pdf, .png, .jpg, .jpeg, and .svg are written with a Matplotlib renderer that does not require Kaleido or Chrome. .html and .htm are written as self-contained interactive Plotly files.

Parameters:
  • fig (plotly.graph_objects.Figure) – Figure to export.

  • save_path (str) – Desired output path.

Return type:

str

Returns:

str – The final path written to disk.

Raises:

RuntimeError – If export fails or the chosen output extension is unsupported.

Layout Helpers

Show Layout Utilities

This module defines layout policies for the show command’s Plotly figures.

It centralizes three kinds of behavior:

  • Grid geometry: choose a compact (rows, cols) arrangement for the single-channel case.

  • Axis constraints: enforce square pixels and deterministic zoom-linking behavior across subplot layouts.

  • Decorations: draw per-file row frames (multi-channel case) and per-panel filename “pills” (single-channel grid case). All decoration placement is converted from pixel offsets into Plotly “paper” coordinates to keep the appearance stable as figure size changes.

Constants

ACCENT

Accent color used for outlines and highlighted text.

ACCENT_SOFT

Soft accent color used for subtle backgrounds.

BG_PAGE

Page background color.

BG_PANEL

Panel background color (reserved for future use).

BG_CARD

Card/plot background color.

FG

Foreground text color.

BORDER

Border color used for pill outlines.

Functions

grid_shape_smart

Choose a compact (rows, cols) grid for n panels.

apply_aspect_ratio_lock

Enforce square pixels in every subplot using Plotly axis constraints.

build_zoom_payloads

Build relayout payloads for zoom-linking modes (all, file, none).

apply_default_zoom_matches

Apply an initial zoom-linking mode directly to the figure layout.

add_panel_title_pills

Add per-panel filename pills in the single-channel grid layout.

add_file_row_frames

Draw a rectangular frame and header band for each file row in the multi-channel layout.

GONet_Wizard.commands.show.layout.grid_shape_smart(n)[source]

Choose a compact (rows, cols) grid for n panels.

Parameters:

n (int) – Number of panels.

Return type:

tuple[int, int]

Returns:

tuple [int, int] – (rows, cols) for a compact grid.

Raises:

ValueError – If n is less than 1.

GONet_Wizard.commands.show.layout.apply_aspect_ratio_lock(fig, *, rows, cols)[source]

Lock pixel aspect ratio for all subplots (square pixels).

This ensures that image pixels remain square when zooming or resizing, by tying each y-axis scale to its corresponding x-axis.

Parameters:
  • fig (plotly.graph_objects.Figure) – Target figure.

  • rows (int) – Number of subplot rows.

  • cols (int) – Number of subplot columns.

Return type:

None

Returns:

None

GONet_Wizard.commands.show.layout.build_zoom_payloads(*, rows, cols, per_file_rows)[source]

Build relayout payloads for the zoom-linking modes used by the HTML controls.

Parameters:
  • rows (int) – Number of subplot rows.

  • cols (int) – Number of subplot columns.

  • per_file_rows (bool) – Whether the layout is “one row per file”.

Return type:

dict[str, dict]

Returns:

dict [str, dict] – Mapping of 'all', 'file', and 'none' to Plotly relayout payload dictionaries.

GONet_Wizard.commands.show.layout.apply_default_zoom_matches(fig, *, rows, cols, mode, per_file_rows)[source]

Apply an initial zoom-linking mode directly to the figure layout.

This is used to set the starting state of axis matching, before any HTML controls call plotly.graph_objects.Figure.relayout().

Parameters:
  • fig (plotly.graph_objects.Figure) – Target figure.

  • rows (int) – Number of subplot rows.

  • cols (int) – Number of subplot columns.

  • mode (str) – Initial mode ('all', 'file', or 'none').

  • per_file_rows (bool) – Whether the layout is “one row per file”.

Return type:

None

Returns:

None

GONet_Wizard.commands.show.layout.add_panel_title_pills(fig, *, rows, cols, titles, title_max_chars=42, title_pad_x_px=12, title_pad_y_px=-10)[source]

Add per-panel title pills for the single-channel grid layout.

Each pill is an annotation placed inside the corresponding subplot, near the top-left corner. Offsets are specified in pixels and converted into paper coordinates using the figure’s plot area, so placement remains stable under deterministic resizing.

Parameters:
  • fig (plotly.graph_objects.Figure) – Target figure.

  • rows (int) – Number of subplot rows.

  • cols (int) – Number of subplot columns.

  • titles (list [str]) – Title strings in subplot insertion order (the same order used when traces are added).

  • title_max_chars (int, optional) – Maximum displayed length; longer titles are truncated with an ellipsis.

  • title_pad_x_px (int, optional) – X offset from the subplot’s left edge, in pixels.

  • title_pad_y_px (int, optional) – Y offset relative to the subplot’s top edge, in pixels. Negative values move the pill downward into the panel.

Return type:

None

Returns:

None

GONet_Wizard.commands.show.layout.add_file_row_frames(fig, *, rows, cols, row_titles, pad_x_px=12, pad_y_px=10, header_px=56, label_y_px=22, title_max_chars=70)[source]

Draw a frame around each file-row and reserve a constant-height header band.

This is used for the multi-channel layout (one row per file). Two things happen per row:

  1. Reserve header height in pixels by shrinking each subplot’s y-domain upward, leaving a consistent band for column labels.

  2. Create breathing room at the left/right edges by shrinking each subplot’s x-domain inward by pad_x_px (converted to paper fraction). This avoids image traces visually “touching” the row border.

Parameters:
  • fig (plotly.graph_objects.Figure) – Target figure.

  • rows (int) – Number of subplot rows (files).

  • cols (int) – Number of subplot columns (channels).

  • row_titles (list [str]) – One title per row. Values are truncated to title_max_chars.

  • pad_x_px (int, optional) – Horizontal padding in pixels used to shrink subplot x-domains.

  • pad_y_px (int, optional) – Extra padding below the row frame, in pixels.

  • header_px (int, optional) – Header band height reserved inside each row, in pixels.

  • label_y_px (int, optional) – Vertical placement for the column labels within the header band, in pixels.

  • title_max_chars (int, optional) – Maximum displayed title length; longer titles are truncated with an ellipsis.

Return type:

None

Returns:

None