spacr.qt.widgets.figure_settings¶
Restyle and export live Matplotlib figures from the Qt interface.
The settings dialog builds its controls from the artists present in a figure, so only applicable options are shown. It can update data-dependent properties, such as axis scales, without rerunning the analysis. This module also manages reusable graph-style files and optional data, statistics, and caption sidecars.
Classes¶
Edit the supported appearance settings of a live figure. |
|
Edit general and graph-specific figure-style preferences. |
Functions¶
|
Add graph-style save and load actions to a menu. |
|
Apply one colour to every text object in a figure. |
|
Save graph-style overrides as the active preferences. |
|
Apply one colour to figure lines, spines, and tick marks. |
|
Build the context menu for a displayed figure. |
|
Derive a grouped-plot recipe from an existing matplotlib figure. |
|
Export available figure data, statistics, and caption sidecars. |
|
Restore line and font colours from the active theme preferences. |
|
Collect artists affected by the global line-colour control. |
|
Serialize graph-style preference overrides to a dictionary. |
|
Read graph-style preference overrides from a JSON file. |
|
Save a figure using its current styling and export preferences. |
|
Export a Matplotlib figure with its source data and statistics. |
|
Write graph-style preference overrides to a JSON file. |
|
Return the choices available for a style setting. |
|
Convert a style setting name to a display label. |
Module Contents¶
- class spacr.qt.widgets.figure_settings.FigureSettingsDialog(figure, parent=None, *, on_change: Callable | None = None, propagate_callback: Callable | None = None)[source]¶
Bases:
PySide6.QtWidgets.QDialogEdit the supported appearance settings of a live figure.
Controls are created from the figure’s current axes, artists, legends, and optional spaCR metadata. Changes are previewed after a short debounce; rejecting the dialog restores the opening state when it could be captured.
Build the figure settings dialog with a live preview.
A pickled snapshot of the figure is taken so Cancel has something to go back to: live apply with no way out is a trap – the user drags a spin box to see what it does and there is no longer an “as it was”. The per-figure text-size override is kept separately, because Cancel restores the figure by copying axes out of the snapshot rather than by swapping the object, so that attribute would otherwise survive an undo of everything it applies to.
The Statistics tab appears only for a figure that compares groups: one offering a t-test on a Q-Q plot would be an invitation to report a number that means nothing. The UMAP tab appears only for a figure carrying the embedding it was drawn from – without it, “live” would mean re-running the reduction and every point would move.
- Parameters:
figure – the matplotlib figure to restyle.
parent – parent widget, or
None.on_change – called to redraw; takes
previewwhen it can.propagate_callback – writes the values into the owning module’s settings panel.
Nonedisables Propagate and says why.
- closeEvent(event)[source]¶
Complete a full-quality redraw before closing the dialog.
- Parameters:
event (PySide6.QtGui.QCloseEvent) – Qt close event forwarded to the parent implementation.
- eventFilter(obj, event)[source]¶
Prevent unfocused inputs from consuming scroll-wheel events.
- Parameters:
obj (PySide6.QtCore.QObject) – Object receiving the event.
event (PySide6.QtCore.QEvent) – Event being filtered.
- Returns:
bool –
Truewhen an unfocused input’s wheel event was consumed; otherwise the result from the parent event filter.
- class spacr.qt.widgets.figure_settings.FigureStylePreferences(general=None, per_graph=None, parent=None)[source]¶
Bases:
PySide6.QtWidgets.QWidgetEdit general and graph-specific figure-style preferences.
General settings apply to every figure. Each graph type can override only the settings it needs, and the panel stores differences from package defaults rather than a fully resolved style.
Build the figure-style preference page.
- Parameters:
general – the saved general style values; missing keys fall back to the shipped defaults.
per_graph – saved per-graph-kind overrides, keyed by kind.
parent – parent widget, or
None.
- apply_values(general=None, per_graph=None) None[source]¶
Load style overrides into the preference controls.
- Parameters:
general (mapping, optional) – General style overrides.
per_graph (mapping of str to mapping, optional) – Style overrides keyed by graph type.
Notes
A control omitted from the supplied mappings is reset to its package default rather than retaining its previous value.
- spacr.qt.widgets.figure_settings.add_graph_style_file_entries(menu, parent=None, *, on_change=None) None[source]¶
Add graph-style save and load actions to a menu.
- Parameters:
menu (PySide6.QtWidgets.QMenu) – Menu that receives the actions.
parent (PySide6.QtWidgets.QWidget, optional) – Parent for file dialogs and actions. If
None, usemenu.on_change (callable, optional) – Callback invoked after a style is loaded. Callbacks may accept a
previewkeyword argument.
- spacr.qt.widgets.figure_settings.apply_font_colour(figure, colour) int[source]¶
Apply one colour to every text object in a figure.
- Parameters:
figure (matplotlib.figure.Figure) – Figure to update.
colour (Any) – Matplotlib colour specification.
- Returns:
int – Number of text objects successfully updated. This includes titles, axes labels, tick labels, legends, and annotations.
- spacr.qt.widgets.figure_settings.apply_graph_style(general, per_graph) None[source]¶
Save graph-style overrides as the active preferences.
- Parameters:
general (mapping) – General style overrides.
per_graph (mapping of str to mapping) – Style overrides keyed by graph type. Values that are not mappings are omitted.
- spacr.qt.widgets.figure_settings.apply_line_colour(figure, colour) int[source]¶
Apply one colour to figure lines, spines, and tick marks.
Line styles and dash patterns are preserved. Gridlines and text are not changed.
- Parameters:
figure (matplotlib.figure.Figure) – Figure to update.
colour (Any) – Matplotlib colour specification.
- Returns:
int – Number of line, spine, and legend artists successfully updated. Tick marks are updated separately and are not included in this count.
Build the context menu for a displayed figure.
The menu provides direct legend, grid, scale, colour, and export actions. Figures with grouped-plot metadata can also be redrawn as another plot type. More detailed controls are delegated to
open_settings.- Parameters:
parent (PySide6.QtWidgets.QWidget) – Parent for the returned menu and its dialogs.
figure (matplotlib.figure.Figure or None) – Figure to edit. If
None, the menu contains a disabled status action.on_change (callable, optional) – Callback invoked after a direct edit. Callbacks may accept a
previewkeyword argument or a replacement figure.open_settings (callable, optional) – Callback invoked by the
Figure settingsaction.
- Returns:
PySide6.QtWidgets.QMenu – Context menu owned by
parent.
- spacr.qt.widgets.figure_settings.derive_replot_recipe(figure)[source]¶
Derive a grouped-plot recipe from an existing matplotlib figure.
This fallback supports figures without a
_spacr_replotpayload by reading plotted values from bars, scatter collections, and data lines on a single axes. Artist-derived data are exact for bar heights and point coordinates but are necessarily lossy for summary artists such as box or violin plots, which do not retain their source observations. Figures created byspacr.plot.create_grouped_plot()use their attached source frame instead of this fallback.- Parameters:
figure – Matplotlib
Figurecontaining exactly one axes.- Returns:
Recipe dictionary for
spacr.plot.create_grouped_plot(), orNonewhen sufficient plottable values cannot be recovered.
- spacr.qt.widgets.figure_settings.export_sidecars(figure, path) list[source]¶
Export available figure data, statistics, and caption sidecars.
- Parameters:
figure (matplotlib.figure.Figure) – Figure carrying optional
_spacr_data,_spacr_groups, or_spacr_captionmetadata.path (path-like) – Figure output path. Sidecars use the same directory and basename.
- Returns:
list of str – Successfully written sidecar paths. Depending on available metadata, these may include
<name>.csv,<name>_stats.csv, and<name>_legend.txt.
Notes
The data sidecar contains the rows attached to the rendered figure. The statistics sidecar contains all usable pairwise comparisons with multiple testing correction provided by spaCR’s statistics table helper. Individual sidecar failures are logged and do not interrupt the remaining exports.
- spacr.qt.widgets.figure_settings.figure_follows_the_theme(figure) None[source]¶
Restore line and font colours from the active theme preferences.
- Parameters:
figure (matplotlib.figure.Figure) – Figure to update. If the preference store is unavailable, black is used for both line and font colours.
- spacr.qt.widgets.figure_settings.figure_line_artists(figure) list[source]¶
Collect artists affected by the global line-colour control.
- Parameters:
figure (matplotlib.figure.Figure) – Figure whose artists should be collected.
- Returns:
list – Data and reference lines, axes spines, and legend sample lines.
Notes
Gridlines are excluded. Tick marks are updated separately by
apply_line_colour()because Matplotlib recreates them during draws.
- spacr.qt.widgets.figure_settings.graph_style_as_dict(general=None, per_graph=None) dict[source]¶
Serialize graph-style preference overrides to a dictionary.
- Parameters:
general (mapping, optional) – General style overrides. If
None, read the current preference.per_graph (mapping of str to mapping, optional) – Overrides keyed by graph type. If
None, read the current preference.
- Returns:
dict – Style data with
spacr_style_kind,general, andper_graphkeys. Per-graph values that are not mappings are omitted.
Notes
Only preference overrides are stored. Theme-resolved colours and package defaults are not captured from the currently displayed figure.
- spacr.qt.widgets.figure_settings.load_graph_style(path: str) tuple[source]¶
Read graph-style preference overrides from a JSON file.
- Parameters:
path (str) – Path to a graph-style file created by
save_graph_style().- Returns:
general (dict) – General style overrides.
per_graph (dict) – Style overrides keyed by graph type.
- Raises:
OSError – If the file cannot be opened.
json.JSONDecodeError – If the file does not contain valid JSON.
ValueError – If the file is not identified by
GRAPH_STYLE_FILE_KIND.
Notes
Unknown setting names are preserved for compatibility with files created by other spaCR versions.
- spacr.qt.widgets.figure_settings.save_figure_as(parent, figure, path: str = '') str[source]¶
Save a figure using its current styling and export preferences.
- Parameters:
parent (PySide6.QtWidgets.QWidget or None) – Parent for the file chooser when
pathis empty.figure (matplotlib.figure.Figure or None) – Figure to save.
Nonecancels the operation.path (str, optional) – Destination path. If empty, prompt for a PNG, PDF, or SVG path.
- Returns:
str – Path returned by the writer, or an empty string when saving is cancelled or fails.
Notes
A recognized filename extension takes precedence over the default output format. Available data, statistics, and caption metadata are exported by
export_sidecars()beside the requested path.
- spacr.qt.widgets.figure_settings.save_figure_bundle(figure, folder: str, name: str = '') str[source]¶
Export a Matplotlib figure with its source data and statistics.
Group definitions come from the attached replot recipe so statistical comparisons match the displayed figure. When no recipe is available, the standard files are still written and the statistics artifact records that no comparison could be formed.
- Parameters:
figure – Matplotlib figure to export.
folder – destination directory for the bundle.
name – optional base name for generated files.
- Returns:
path to the written bundle directory.
- spacr.qt.widgets.figure_settings.save_graph_style(path: str, general=None, per_graph=None) str[source]¶
Write graph-style preference overrides to a JSON file.
- Parameters:
path (str) – Destination path. An empty path cancels the operation.
general (mapping, optional) – General style overrides. If
None, read the current preference.per_graph (mapping of str to mapping, optional) – Overrides keyed by graph type. If
None, read the current preference.
- Returns:
str –
pathafter a successful write, or an empty string if the path is empty or the file cannot be written.- Raises:
TypeError – If a supplied setting value cannot be serialized as JSON.
- spacr.qt.widgets.figure_settings.style_choices_for(name: str) tuple[source]¶
Return the choices available for a style setting.
- Parameters:
name (str) – Style setting name.
- Returns:
tuple – Canonical choices from
spacr.figure_style. If that module is unavailable, return the local fallback choices. An empty tuple denotes a free-form or unknown setting.
Nested helpers¶
- FigureSettingsDialog._add_series_rules.apply_edge(value)¶
Set the edge width on every series that has one.
spacr/qt/widgets/figure_settings.py:397
- FigureSettingsDialog._add_series_rules.apply_opacity(value)¶
Set the alpha on every series.
spacr/qt/widgets/figure_settings.py:384
- FigureSettingsDialog._add_series_rules.apply_palette(*_)¶
Recolour every series from the chosen palette.
spacr/qt/widgets/figure_settings.py:344
- FigureSettingsDialog._add_series_rules.apply_size(value)¶
Resize every series that has a size to set.
spacr/qt/widgets/figure_settings.py:368
- FigureSettingsDialog._axes_tab.apply_grid(*_)¶
Show or hide the grid, passing line properties ONLY when enabling.
matplotlib warns “First parameter to grid() is false, but line properties are supplied” and then turns the grid ON regardless – so passing them unconditionally made the checkbox unable to switch the grid off, which is the opposite of what it says.
spacr/qt/widgets/figure_settings.py:822
- FigureSettingsDialog._axes_tab.apply_legend(*_)¶
Rebuild the legend from the current choices.
spacr/qt/widgets/figure_settings.py:899
- FigureSettingsDialog._axes_tab.apply_limits(*_, s=setter, b=boxes)¶
Apply one axis’s limits, refusing a zero-width range.
Equal bounds collapse the axis and matplotlib draws nothing, so the value is left alone rather than applied.
spacr/qt/widgets/figure_settings.py:776
- FigureSettingsDialog._axes_tab.do_autoscale()¶
Recompute the limits from the data now on the axis.
spacr/qt/widgets/figure_settings.py:793
- FigureSettingsDialog._axes_tab.set_colour(colour, a=artist)¶
Recolour one artist. The artist is bound as a default argument.
Bound at definition rather than closed over: a loop variable closed over gives every callback the LAST artist, which is the classic way a row of per-artist controls all end up editing one of them.
spacr/qt/widgets/figure_settings.py:938
- FigureSettingsDialog._axes_tab.set_spines(value)¶
Set every spine’s width, or hide them all at zero.
spacr/qt/widgets/figure_settings.py:854
- FigureSettingsDialog._axes_tab.set_top_right(hidden)¶
Hide or show the top and right spines together.
spacr/qt/widgets/figure_settings.py:867
- FigureSettingsDialog._figure_tab.resize(*_)¶
Resize the figure to the width and height on screen.
spacr/qt/widgets/figure_settings.py:650
- FigureSettingsDialog._figure_tab.set_all_text(size)¶
Set one font size on every piece of text in the figure.
spacr/qt/widgets/figure_settings.py:670
- FigureSettingsDialog._figure_tab.set_face(colour)¶
Set the figure’s own background colour.
spacr/qt/widgets/figure_settings.py:634
- FigureSettingsDialog._figure_tab.set_font_ink(colour)¶
Recolour every piece of text in the figure.
spacr/qt/widgets/figure_settings.py:689
- FigureSettingsDialog._figure_tab.set_line_ink(colour)¶
Recolour every line in the figure.
spacr/qt/widgets/figure_settings.py:684
- FigureSettingsDialog._statistics_tab._recompute()¶
Re-run the test with the current choices and redraw.
spacr/qt/widgets/figure_settings.py:581
- FigureStylePreferences._control._set_colour(v, b=button, h=holder)¶
Store a colour and repaint the swatch that shows it.
spacr/qt/widgets/figure_settings.py:2926
- FigureStylePreferences._control._set_combo(v, box=combo)¶
Select the entry whose data is
v, if the box has one.spacr/qt/widgets/figure_settings.py:2915
- FigureStylePreferences._ground_control._get()¶
The ground: the transparent sentinel, or the chosen colour.
spacr/qt/widgets/figure_settings.py:2991
- FigureStylePreferences._ground_control._paint_button(colour: str) None¶
Show the ground colour on the button, as swatch and text.
spacr/qt/widgets/figure_settings.py:2976
- FigureStylePreferences._ground_control._set(new_value)¶
Apply a ground, ticking transparent when that is what it means.
spacr/qt/widgets/figure_settings.py:2996
- FigureStylePreferences._ground_control._sync(*_)¶
Grey the colour button while transparent is ticked.
spacr/qt/widgets/figure_settings.py:2985
- _add_bundle_save._save() None¶
Ask for a folder and write the whole bundle into it.
spacr/qt/widgets/figure_settings.py:1624
- _add_group_colours._recolour(group: str) None¶
Pick a colour for one group and store it on the recipe.
spacr/qt/widgets/figure_settings.py:1587
- _colour_button._choose()¶
Ask for a colour and keep it if the dialog returned one.
spacr/qt/widgets/figure_settings.py:99
- _colour_button._paint()¶
Show the current colour on the button, as a swatch and as text.
spacr/qt/widgets/figure_settings.py:90
- add_graph_style_file_entries._load()¶
Read a graph style back and apply it.
spacr/qt/widgets/figure_settings.py:1303
- add_graph_style_file_entries._save()¶
Write the current graph style to a JSON file.
spacr/qt/widgets/figure_settings.py:1295
Run
funcagainst every axis in the figure.spacr/qt/widgets/figure_settings.py:1791
Redraw after a menu toggle, CHEAPLY.
A context-menu toggle is the same kind of edit the settings dialog makes, and the dialog learned long ago to preview: a full-quality render rewrites the raster AND the vector page, measured at ~263 ms on an 823-point volcano, and the user is mid-gesture. Preview here too, and let the next full render – a resize, an export, closing the settings dialog – catch up.
on_changemay be a callable that predates preview rendering, so the keyword is offered and withdrawn rather than assumed.spacr/qt/widgets/figure_settings.py:1771
Pick a colour and apply it through
apply_to.spacr/qt/widgets/figure_settings.py:1843
Show or hide the legend on every axis.
spacr/qt/widgets/figure_settings.py:1804
- save_figure_as.figure_bg_is_transparent(value)¶
Whether a stored ground value means “no background at all”.
spacr/qt/widgets/figure_settings.py:2469
- save_figure_bundle._render(path: str) None¶
Render one file of the bundle through the SHARED export path.
Both formats go through
save_figurerather than each drawing itself, so print colours, embedded fonts and raster DPI match every other figure the user keeps.spacr/qt/widgets/figure_settings.py:1665