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:
commanddefines the CLICommandSpecand thecli_handler().figureconstructs the Plotlyplotly.graph_objects.Figureused by the command.layoutprovides deterministic layout policy (subplot geometry, aspect locking, and zoom-linking payloads).iocontains 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
CommandSpecfor theshowcommand.
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
showoutput as a standalone HTML document.The handler:
Resolves input files and channel selection from CLI arguments.
Builds a Plotly figure using
build_show_figure().Registers an interactive session for the returned window.
Computes “zoom linking” payloads and emits custom HTML buttons that call
Plotly.relayout(graphDiv, payload).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 figureandExitbuttons.Save figureopens 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 byCOMMAND.- Return type:
- Returns:
strorNone– A complete HTML document as a string. If your surrounding CLI framework supports “no UI output” paths, this may returnNone(currently unused).- Raises:
FileNotFoundError – If the required CSS file (
STATIC/css/style.css) is missing.ValueError – If no channels are selected.
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:
per-file row frames (multi-channel case) via
add_file_row_frames(), orper-panel filename “pills” (single-channel grid case) via
add_panel_title_pills().
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
Figurefor theshowcommand.- _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 forvmin. Defaults to0.5.upper_percentile (
float, optional) – Upper percentile used forvmax. Defaults to99.5.
- Return type:
- Returns:
tuple[float,float] –(vmin, vmax)suitable for Plotlyzmin/zmax.
Notes
If percentile computation results in non-finite or degenerate bounds, this falls back to
min/maxof finite values and enforcesvmax > 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
showcommand.- Parameters:
files (
collections.abc.Sequence[strorpathlib.Path]) – Input file paths.channels (
collections.abc.Sequence[str]) – Channel names to plot. If length is1, a compact grid is used. If length is greater than1, 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
channelsis 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_pathhas no extension,.pdfis appended. Static extensions.pdf,.png,.jpg,.jpeg, and.svgare written with a Matplotlib renderer that does not require Kaleido or Chrome..htmland.htmare written as self-contained interactive Plotly files.- Parameters:
fig (
plotly.graph_objects.Figure) – Figure to export.save_path (
str) – Desired output path.
- Return type:
- 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 fornpanels.- 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 fornpanels.
- 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.
- 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.
- 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().
- 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:
- 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:
Reserve header height in pixels by shrinking each subplot’s y-domain upward, leaving a consistent band for column labels.
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 totitle_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:
- Returns:
None