plot

Plot utilities for interactive visualization of GONet sky monitoring data.

This module provides Plotly-compatible wrappers and helper classes for rendering, filtering, and interacting with GONet dashboard plots in a Dash application. It includes specialized data structures that extend standard Python types (e.g., dict) to support reactive behavior, styling changes, and integration with user inputs like selections and click events.

Classes

  • Trace:

    A dictionary-like wrapper for a single Plotly scatter trace with built-in styling logic tied to filter and visibility states. Automatically updates marker opacity and hover behavior when filtered or hidden flags are set.

  • FigureWrapper:

    A manager class that encapsulates a complete Plotly figure dictionary and provides high-level methods for trace filtering, channel updates, visibility toggling, point selection, and summary statistics. Designed to maintain JSON-serializability for use in Dash callbacks.

This module is intended to serve as the plotting backend for the GONet dashboard UI.

Classes:

class GONet_Wizard.GONet_dashboard.src.hood.plot.Trace(x_label, y_label, channel)[source]

Bases: dict

A specialized dictionary-like object representing a single Plotly scatter trace with automatic styling and visibility behavior. This class is intended to be used in applications like Dash where Plotly figures must remain JSON-serializable, but where it is useful to treat individual traces as stateful, reactive objects.

This wrapper class auto-initializes a full trace structure upon creation, and includes logic to modify the trace’s appearance when certain semantic fields (filtered, hidden) are updated.

Reactive Key Behaviors

  • Setting filtered = True:
    • Reduces marker opacity to 0.2.

  • Setting filtered = False:
    • Restores marker opacity to 1.0.

  • Setting hidden = True:
    • Sets marker opacity to 0 (fully transparent),

    • Disables hover information,

    • Sets marker line width to 0 (if applicable).

  • Setting hidden = False:
    • Sets opacity back to 0.2 (like a filtered trace),

    • Restores hover information and hovertemplate,

    • Sets marker line width to 2 (if applicable).

  • Changing the marker key will automatically change the unselected marker as well.

Notes

  • This class behaves like a dictionary and can be appended directly to a Plotly figure’s data list.

  • It is fully JSON-serializable and can be passed to Dash components.

  • You must use this class instead of a plain dictionary if you want the special reactive behavior described above.

class GONet_Wizard.GONet_dashboard.src.hood.plot.FigureWrapper(fig, x_label, y_label, all_data)[source]

Bases: object

A stateful wrapper around a Plotly figure dictionary for interactive visualization in the GONet dashboard.

This class manages trace creation, filtering, visibility toggling, and interactivity for a multi-channel Plotly scatter plot. It provides a high-level API to dynamically update plots in response to user interactions (e.g., selection filters, click events, channel switching) while maintaining JSON-compatibility for use in Dash callbacks.

Key Features

  • Stores a reference to the full data (all_data) and x/y labels

  • Tracks currently plotted channels and filter state

  • Separates traces into normal, filtered, and big-point variants per channel

  • Automatically updates trace styling and visibility when filters change

  • Supports reconstruction from serialized figures (from_fig)

  • Integrates with environment configuration (e.g., colors, filter ops)

Recommended Entry Point

Use FigureWrapper.build() to initialize a fresh figure and add traces for each channel. Alternatively, use from_fig() to restore a figure after a Dash callback round trip.

fig

The full Plotly figure dictionary (layout + traces), modified in-place.

Type:

dict

x_label

Name of the data field plotted on the x-axis.

Type:

str

y_label

Name of the data field plotted on the y-axis.

Type:

str

all_data

Full GONet dataset used for plotting, including x/y values, filters, and channels.

Type:

dict

channels

Currently visible channels in the figure.

Type:

list of str

total_filter

Boolean array (same length as data) representing active filtering state.

Type:

np.ndarray

show_filtered_points

Whether to display filtered-out points with reduced opacity or hide them entirely.

Type:

bool

big_point_idx

Index of the currently selected “big point” for highlighting and image preview.

Type:

int or None

Notes

  • Each channel has three associated traces: visible, filtered, and big-point.

  • Traces are dynamically updated using filter_traces, update_filters, and apply_visibility.

  • All traces are Plotly- and Dash-compatible (JSON-serializable).

__init__(fig, x_label, y_label, all_data)[source]

Initialize a FigureWrapper with an existing Plotly figure and data source.

This constructor sets up the internal state of the wrapper using an existing Plotly figure dictionary, axis labels, and the full dataset. It initializes filters, channel tracking, and big-point selection support.

Parameters:
  • fig (dict) – A Plotly-compatible figure dictionary. This should contain a layout key with axis configurations and a data list for trace dictionaries or Trace objects.

  • x_label (str) – The field name used for the x-axis (must be a key in all_data).

  • y_label (str) – The field name used for the y-axis (must be a key in all_data).

  • all_data (dict) –

    The full data dictionary used by the dashboard. It should contain at minimum:

    • ’channel’: array of channel labels

    • ’idx’: array of global image indices

    • All fields needed for plotting and filtering

classmethod build(x_label, y_label, channels, all_data)[source]

Construct a new FigureWrapper with default layout and one trace per channel.

This method initializes a Plotly figure dictionary with a standardized layout and styling settings based on the GONet dashboard environment. It then creates a new FigureWrapper instance and populates it with traces for each requested channel.

If both x_label and y_label refer to general (non-channel-specific) quantities, only a single trace is created using channel “gen” as a placeholder.

Parameters:
  • x_label (str) – The quantity to be used for the x-axis. This must be a key in all_data.

  • y_label (str) – The quantity to be used for the y-axis. This must be a key in all_data.

  • channels (list of str) – A list of channel names (e.g., [‘red’, ‘green’, ‘blue’]) to generate traces for.

  • all_data (dict) –

    The full dataset dictionary containing:

    • ’idx’: global index values

    • All fields referenced by x_label, y_label, and filters

Returns:

A new wrapper object containing the initialized figure and all traces.

Return type:

FigureWrapper

Notes

  • Time-based x-labels (starting with ‘hours_’) are formatted as HH:MM.

  • The method uses env.LABELS[‘gen’] to determine if the selected axes are non-channel-specific.

  • This is the standard entry point for figure creation at the beginning of a session.

classmethod from_fig(fig, all_data)[source]

Reconstruct a FigureWrapper from an existing Plotly figure dictionary.

This method is used to rehydrate a previously serialized Plotly figure back into a fully functional FigureWrapper instance. It restores internal logic such as:

  • Trace interactivity via the Trace wrapper

  • Active channels

  • Selection state (big_point_idx)

  • Visibility toggle for filtered points

Parameters:
  • fig (dict) –

    A Plotly-compatible figure dictionary, typically from a callback. It must include:

    • ’layout’: with axis title strings under xaxis.title.text and yaxis.title.text

    • ’data’: a list of trace dictionaries, each with at least a ‘channel’ field

  • all_data (dict) – The full dataset originally used to construct the figure, including the keys referenced by each trace’s ‘x’, ‘y’, and ‘idx’ attributes. This is needed to restore filtering, indexing, and interactivity.

Returns:

A fully reconstructed FigureWrapper with trace semantics, filter states, and internal configuration restored.

Return type:

FigureWrapper

Notes

  • Each trace in fig[‘data’] is converted into a Trace object.

  • Channels are inferred from the ‘channel’ field in each trace.

  • If a trace is marked as big_point, its associated idx[0] is stored as big_point_idx.

  • If any trace is marked as hidden, show_filtered_points is set to False.

  • This method assumes that all necessary metadata exists in the figure dictionary and that all_data is consistent with what was used to generate the figure.

to_dict()[source]

Return the underlying figure dictionary.

Returns:

The Plotly figure dictionary.

Return type:

dict

add_trace(channel)[source]

Add a new set of traces to the figure for a given channel.

This method creates three separate traces for the specified channel:

  • A primary trace for visible (unfiltered) points

  • A secondary trace for filtered (low-opacity) points

  • A third trace for the currently selected “big point”

The traces are appended in order to the Plotly figure’s data list. Styling and visibility behaviors are configured using the Trace class, which responds to keys like filtered, hidden, and big_point.

Parameters:

channel (str) – The name of the data channel to visualize (e.g., ‘red’, ‘green’, ‘blue’).

Return type:

None

filter_traces(channel)[source]

Apply the current filter mask to all traces associated with a specific channel.

This method updates the x, y, and idx values of traces in the figure based on whether they should be shown as filtered or not, using the self.total_filter boolean mask and the specified data channel.

For “big point” traces, it toggles the filtered attribute depending on whether the corresponding index appears in the active subset. For other traces, it directly updates their data arrays with filtered or excluded values.

Parameters:

channel (str) – The name of the data channel to apply filtering to. If ‘gen’ is passed, it will default to ‘red’ for trace alignment purposes.

Return type:

None

update_visibility(show_filtered_points)[source]

Update the visibility flag for filtered points.

This method sets the internal flag controlling whether traces marked as filtered should be displayed or hidden in the plot. It does not directly modify the figure; you must call apply_visibility() afterward to apply the change.

Parameters:

show_filtered_points (bool) – If True, filtered points will be shown with reduced opacity. If False, filtered points will be hidden entirely.

Return type:

None

apply_visibility()[source]

Apply the current visibility setting to all filtered traces.

This method updates the ‘hidden’ property of each trace based on whether filtered points should be shown or hidden. It uses the internal flag self.show_filtered_points, which can be modified via update_visibility().

Traces with filtered = True will be: :rtype: None

  • Shown with reduced opacity if show_filtered_points is True

  • Fully hidden if show_filtered_points is False

update_channels(new_channels)[source]

Add or remove traces to match a new list of active channels.

Parameters:

new_channels (list) – The updated list of channels to be shown.

Notes

  • Traces with ‘channel’ not in new_channels are removed.

  • Traces for new channels are added with default settings and shared data.

update_filters(active_filters)[source]

Update the global filter mask based on the provided list of active filters.

This method processes each filter definition and updates self.total_filter, a boolean mask indicating which data points should be retained. Filters may be simple threshold-based comparisons or special selection-based filters using image indices.

Each filter is interpreted as either:

  • A selection filter: matches image indices (label == “Selection …”)

  • A numeric filter: compares a field against a value using a specified operator from env.OP, with optional secondary filter logic.

Parameters:

active_filters (list of dict) –

Each filter dict must include:

  • ’label’ : str — the field name or “Selection …”.

  • ’operator’ : str — key in env.OP for the comparison function.

  • ’value’ : comparable — the value to compare against.

Optionally:

  • ’secondary’ : dict — a nested filter with the same keys (‘label’, ‘operator’, ‘value’).

Return type:

None

Notes

  • All filters are combined using logical AND.

  • Secondary filters are combined with the primary using logical OR.

  • The resulting self.total_filter array is used by filter_traces() to control visibility.

gather_big_point(clickdata)[source]

Update the index of the selected “big point” based on click interaction data.

This method extracts the index of the clicked point from Plotly’s clickData dictionary and stores it in self.big_point_idx. This index is later used for highlighting or retrieving detailed information about the selected point.

Parameters:

clickdata (dict) –

A dictionary passed from a Dash Plotly clickData callback. It must contain a ‘points’ list with at least one item, each including:

  • ’curveNumber’: int — the index of the clicked trace in fig[‘data’]

  • ’pointIndex’: int — the index of the clicked point within that trace

Return type:

None

plot_big_point()[source]

Update the figure to highlight the currently selected “big point”.

This method sets the data for the special “big point” trace associated with each channel. It updates the trace with the coordinates of the selected point, based on self.big_point_idx and the current x/y axis labels.

The point is only plotted if both its index and channel match a known data entry. Its filtered flag is also updated depending on whether the point passes the current filter.

Returns:

This method updates the figure in-place.

Return type:

None

Notes

  • The “gen” channel is treated as “red” for indexing purposes.

get_stats()[source]

Compute summary statistics (mean and standard deviation) for plotted x and y values.

This function extracts unfiltered, non-highlighted data from the figure and calculates per-axis statistics. It builds an HTML table as a list of Dash row components to be rendered in the dashboard’s stats panel.

Returns:

A list of dash.html.Tr elements representing the statistics table rows.

Return type:

list

get_data_point_info()[source]

Retrieve detailed metadata for the currently selected “big point”.

This method gathers all relevant information for the data point indexed by self.big_point_idx, combining general metadata and channel-specific fit values into a single dictionary.

General fields (from env.LABELS[‘gen’]) are assumed to be identical across channels and are taken from the first matching index. Channel-specific fields (from env.LABELS[‘fit’]) are extracted separately for each matching channel and labeled accordingly.

Returns:

A dictionary containing the values of all general and fit-related fields for the selected “big point”. Fit values are keyed by {label}_{channel}.

Return type:

dict

gonet_image(clickdata)[source]

Retrieve and render a GONet image corresponding to the selected data point.

This method locates the raw image file corresponding to the clicked data point and generates a Plotly-compatible figure dictionary for display in the dashboard. It overlays the image with a marker at the extraction center and a circular region representing the extraction aperture.

Parameters:

clickdata (dict) –

A Plotly click event dictionary from a Dash callback. Must contain:

  • ’points’: list with at least one entry

  • ’curveNumber’: index of the clicked trace

  • ’pointIndex’: index of the clicked point within the trace

Returns:

A Plotly figure dictionary containing a heatmap of the selected image and overlay annotations. Returns None if the image cannot be loaded due to missing configuration or file.

Return type:

dict or None

Notes

  • This function uses env.GONET_IMAGES_PATH to resolve image file paths.