Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,11 @@ jobs:
--pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background \
--exec /usr/bin/Xvfb -- :99 -screen 0 1920x1200x24 -ac +extension GLX
python -m pip install --upgrade pip
python -m pip install -e ".[dev,test,qt]" matplotlib
- name: Verify PlotPy backend
run: python -c "import plotpy; print(f'PlotPy loaded from {plotpy.__file__}')"
python -m pip install -e ".[dev,test,qt,plotly]" matplotlib
- name: Verify optional visualization backends
run: |
python -c "import plotpy; print(f'PlotPy loaded from {plotpy.__file__}')"
python -c "import plotly; print(f'Plotly loaded from {plotly.__file__}')"
- name: Test visualization backends
run: python -m pytest -o addopts="--import-mode=importlib" sigima/tests/viz -vv
- name: Lint with Pylint
Expand Down
90 changes: 67 additions & 23 deletions doc/api/viz.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ This module provides visualization utilities for Sigima objects, useful for:
Backend Selection
-----------------

The module automatically selects between **PlotPy** and **Matplotlib** backends based on availability and configuration settings.
The module supports **PlotPy**, **Matplotlib**, and **Plotly** backends. The
first two participate in automatic selection; Plotly is selected explicitly.

The backend selection follows this priority:

Expand All @@ -27,6 +28,10 @@ Backend selection logic:
- ``"auto"``: Try PlotPy first, fall back to Matplotlib
- ``"plotpy"``: Use PlotPy (raise :class:`ImportError` if not available)
- ``"matplotlib"``: Use Matplotlib (raise :class:`ImportError` if not available)
- ``"plotly"``: Use browser-based Plotly (raise :class:`ImportError` if not available)

Selecting Plotly does not change the ``"auto"`` priority. Install the optional
dependency with ``pip install "sigima[plotly]"``.

.. rubric:: Configuring the Backend

Expand Down Expand Up @@ -56,7 +61,8 @@ Module Attributes
.. py:data:: BACKEND_NAME
:type: str

Name of the currently selected backend: ``"plotpy"`` or ``"matplotlib"``.
Name of the currently selected backend: ``"plotpy"``, ``"matplotlib"``, or
``"plotly"``.

.. py:data:: BACKEND_SOURCE
:type: str
Expand Down Expand Up @@ -104,10 +110,36 @@ labels, and layer order. Text may be positioned in data coordinates or in
normalized axes coordinates.

PlotPy also displays valid historical ``plotpy_json`` payloads without changing
the object. Matplotlib ignores those opaque renderer-specific payloads. Use
the object. Matplotlib and Plotly ignore those opaque renderer-specific payloads. Use
the explicit migration described in :ref:`api_annotations` to make historical
annotations portable.

Plotly JSON specifications
--------------------------

The :mod:`sigima.viz.plotly_spec` module builds plain JSON-compatible
``dict``/``list`` structures without importing the Plotly Python package. These
specifications may be consumed directly by Plotly.js or materialized as
``plotly.graph_objects.Figure`` objects by the Plotly backend. Overlay builders
are independent from the signal and image arrays so browser applications may
reuse annotations, ROIs, and geometry results without copying large datasets.

.. autofunction:: sigima.viz.plotly_spec.build_curve_figure_spec

.. autofunction:: sigima.viz.plotly_spec.build_image_figure_spec

.. autofunction:: sigima.viz.plotly_spec.build_signal_roi_overlay

.. autofunction:: sigima.viz.plotly_spec.build_image_roi_overlay

.. autofunction:: sigima.viz.plotly_spec.build_geometry_overlay

The autonomous interactive gallery is available from the repository with:

.. code-block:: powershell

python scripts/run_with_env.py python -m pytest sigima/tests/viz/plotly_gallery_gui_test.py --gui -v

Low-Level Viewing Functions
---------------------------

Expand Down Expand Up @@ -149,38 +181,50 @@ Annotation Items
Backend Differences
-------------------

The two backends have different capabilities:
The three backends have different capabilities:

.. list-table::
:header-rows: 1
:widths: 40 30 30
:widths: 34 22 22 22

* - Feature
- PlotPy
- Matplotlib
- Plotly
* - Interactive zoom/pan
- ✅ Full Qt tools
- ✅ Basic toolbar
- Full Qt tools
- Basic toolbar
- Browser tools
* - ROI display
- ✅ Native support
- ✅ Patches overlay
- Native support
- Patches overlay
- JSON overlays
* - Geometry results
- ✅ Shape annotations
- ✅ Markers/lines
- Shape annotations
- Markers/lines
- Shapes/traces
* - Canonical annotations
- ✅ Native interactive items
- ✅ Read-only artists
- Native interactive items
- Read-only artists
- Read-only overlays
* - Historical PlotPy annotations
- ✅ View-only compatibility
- ❌ Opaque payload ignored
- View-only compatibility
- Opaque payload ignored
- Opaque payload ignored
* - Linked axes
- ✅ Native
- ✅ via ``sharex``/``sharey``
- Native
- via ``sharex``/``sharey``
- Plotly subplots
* - Qt integration
- ✅ Native
- ⚠️ Requires Qt backend
- Native
- Requires Qt backend
- Not required
* - Headless/CI
- ⚠️ Needs display
- ✅ ``Agg`` backend

For automated testing and CI environments, Matplotlib with the ``Agg`` backend is recommended. For interactive data exploration, PlotPy provides a richer experience.
- Needs display
- ``Agg`` backend
- JSON validation

For automated testing and CI environments, Matplotlib with the ``Agg`` backend
or the dependency-free Plotly specifications may be used. PlotPy provides Qt
editing tools; Plotly provides an interactive browser view with zoom, pan, and
hover but does not edit canonical annotations.
3 changes: 2 additions & 1 deletion doc/release_notes/release_1.03.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@

### ✨ New features since version 1.2.0 ###

* **Portable graphical annotations**: Signals and images may now carry versioned, renderer-independent points, shapes, text, cursors and axis ranges. Annotations survive Sigima file round trips and supported image transformations, and are displayed consistently by the PlotPy and Matplotlib visualization backends. Existing PlotPy annotations remain readable and can be migrated explicitly while unknown application data is preserved. This implements [Issue #53](https://github.com/DataLab-Platform/Sigima/issues/53).
* **Portable graphical annotations**: Signals and images may now carry versioned, renderer-independent points, shapes, text, cursors and axis ranges. Annotations survive Sigima file round trips and supported image transformations, and are displayed consistently by the PlotPy and Matplotlib visualization backends. Existing PlotPy annotations remain readable and can be migrated explicitly while unknown application data is preserved. This implements [Issue #53](https://github.com/DataLab-Platform/Sigima/issues/53).
* **Interactive Plotly visualization**: Signals and images can now be inspected in a browser with zoom, pan and hover through the optional Plotly backend. Sigima also exposes dependency-free Plotly JSON builders for applications and notebooks, including portable annotation, ROI and geometry-result overlays.
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ doc = [
]
test = ["pytest", "pytest-xvfb", "jsonschema >= 4"]
qt = ["qtpy", "PyQt5", "plotpy"]
plotly = ["plotly >= 5.0"]

[tool.setuptools.packages.find]
include = ["sigima*"]
Expand Down
3 changes: 2 additions & 1 deletion sigima/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,11 +343,12 @@ def __init__(self) -> None:
description=_(
"""Backend library for visualization (sigima.viz module).

Valid values: ``"auto"``, ``"plotpy"``, ``"matplotlib"``.
Valid values: ``"auto"``, ``"plotpy"``, ``"matplotlib"``, ``"plotly"``.

- ``"auto"`` (default): Automatically select PlotPy if available, otherwise Matplotlib
- ``"plotpy"``: Use PlotPy for interactive visualizations (requires PlotPy and Qt)
- ``"matplotlib"``: Use Matplotlib for visualizations (simpler, view-only)
- ``"plotly"``: Use Plotly for browser-based interactive visualizations

This setting can also be overridden using the ``SIGIMA_VIZ_BACKEND`` environment
variable. Note that Matplotlib backend does not support all features of PlotPy
Expand Down
29 changes: 14 additions & 15 deletions sigima/locale/fr/LC_MESSAGES/sigima.po
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,25 @@ msgstr ""
msgid ""
"Backend library for visualization (sigima.viz module).\n"
"\n"
"Valid values: ``\"auto\"``, ``\"plotpy\"``, ``\"matplotlib\"``.\n"
"Valid values: ``\"auto\"``, ``\"plotpy\"``, ``\"matplotlib\"``, ``\"plotly\"``.\n"
"\n"
"- ``\"auto\"`` (default): Automatically select PlotPy if available, otherwise Matplotlib\n"
"- ``\"plotpy\"``: Use PlotPy for interactive visualizations (requires PlotPy and Qt)\n"
"- ``\"matplotlib\"``: Use Matplotlib for visualizations (simpler, view-only)\n"
"- ``\"plotly\"``: Use Plotly for browser-based interactive visualizations\n"
"\n"
"This setting can also be overridden using the ``SIGIMA_VIZ_BACKEND`` environment\n"
"variable. Note that Matplotlib backend does not support all features of PlotPy\n"
"(e.g., ``create_segment()``, ``create_cursor()``, etc. will raise NotImplementedError).\n"
msgstr ""
"Bibliothèque backend pour la visualisation des tests (tests interactifs uniquement).\n"
"\n"
"Valeurs valides : ``\"auto\"``, ``\"plotpy\"``, ``\"matplotlib\"``.\n"
"Valeurs valides : ``\"auto\"``, ``\"plotpy\"``, ``\"matplotlib\"``, ``\"plotly\"``.\n"
"\n"
"- ``\"auto\"`` (par défaut) : Sélectionner automatiquement PlotPy si disponible, sinon Matplotlib\n"
"- ``\"plotpy\"`` : Utiliser PlotPy pour les visualisations interactives (nécessite PlotPy et Qt)\n"
"- ``\"matplotlib\"`` : Utiliser Matplotlib pour les visualisations (plus simple, statique)\n"
"- ``\"plotly\"`` : Utiliser Plotly pour les visualisations interactives dans un navigateur\n"
"\n"
"Ce paramètre peut également être remplacé en utilisant la variable d'environnement ``SIGIMA_VIZ_BACKEND``.\n"
"Notez que le backend Matplotlib ne prend pas en charge toutes les fonctionnalités de PlotPy\n"
Expand Down Expand Up @@ -315,18 +317,18 @@ msgstr "Image sans titre"
msgid "Title"
msgstr "Titre"

msgid "Height"
msgstr "Hauteur"

msgid "Image height: number of rows"
msgstr "Hauteur de l'image : nombre de lignes"

msgid "Width"
msgstr "Largeur"
msgid "Height"
msgstr "Hauteur"

msgid "Image width: number of columns"
msgstr "Largeur de l'image : nombre de colonnes"

msgid "Width"
msgstr "Largeur"

msgid "Type"
msgstr "Type"

Expand Down Expand Up @@ -372,18 +374,18 @@ msgstr "Décalage X"
msgid "Y offset"
msgstr "Décalage Y"

msgid "Minimum value"
msgstr "Minimum"

msgid "Value for dark squares"
msgstr "Valeur des carrés foncés"

msgid "Maximum value"
msgstr "Maximum"
msgid "Minimum value"
msgstr "Minimum"

msgid "Value for light squares"
msgstr "Valeur des carrés clairs"

msgid "Maximum value"
msgstr "Maximum"

msgid "Amplitude and offset"
msgstr "Amplitude et décalage"

Expand Down Expand Up @@ -841,9 +843,6 @@ msgstr "- Infini"
msgid "Replace special values (image)"
msgstr "Remplacer les valeurs spéciales (image)"

msgid "rows"
msgstr "lignes"

msgid "columns"
msgstr "colonnes"

Expand Down
6 changes: 6 additions & 0 deletions sigima/objects/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@
"ImageROI",
"ImageTypes",
"KindShape",
"LegacyPlotPyMigrationReport",
"LinearChirpParam",
"LogisticParam",
"LorentzParam",
Expand Down Expand Up @@ -222,6 +223,8 @@
"flip_annotation_horizontally",
"flip_annotation_vertically",
"is_graphical_annotation_dict",
"legacy_plotpy_payload_to_annotations",
"migrate_legacy_plotpy_annotations",
"rotate_annotation",
"scale_annotation",
"transform_annotation",
Expand All @@ -245,6 +248,7 @@
EllipseAnnotation,
FillStyle,
GraphicalAnnotation,
LegacyPlotPyMigrationReport,
MarkerStyle,
PointAnnotation,
PolygonAnnotation,
Expand All @@ -261,6 +265,8 @@
flip_annotation_horizontally,
flip_annotation_vertically,
is_graphical_annotation_dict,
legacy_plotpy_payload_to_annotations,
migrate_legacy_plotpy_annotations,
rotate_annotation,
scale_annotation,
transform_annotation,
Expand Down
8 changes: 8 additions & 0 deletions sigima/objects/annotations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

"""Renderer-independent graphical annotations."""

from sigima.objects.annotations.legacy_plotpy import (
LegacyPlotPyMigrationReport,
legacy_plotpy_payload_to_annotations,
migrate_legacy_plotpy_annotations,
)
from sigima.objects.annotations.model import (
AnnotationKind,
AnnotationLabel,
Expand Down Expand Up @@ -59,6 +64,7 @@
"EllipseAnnotation",
"FillStyle",
"GraphicalAnnotation",
"LegacyPlotPyMigrationReport",
"MarkerStyle",
"PointAnnotation",
"PolygonAnnotation",
Expand All @@ -75,6 +81,8 @@
"flip_annotation_horizontally",
"flip_annotation_vertically",
"is_graphical_annotation_dict",
"legacy_plotpy_payload_to_annotations",
"migrate_legacy_plotpy_annotations",
"rotate_annotation",
"scale_annotation",
"transform_annotation",
Expand Down
Loading