From 45005211361f13b0c9f75c707843fc54bd0d95e1 Mon Sep 17 00:00:00 2001 From: Neil Vaytet Date: Wed, 17 Apr 2024 15:01:36 +0200 Subject: [PATCH 1/3] move protocols to core module and use FigureLike in return types --- src/plopp/backends/matplotlib/tiled.py | 10 +- src/plopp/backends/matplotlib/utils.py | 2 +- src/plopp/backends/protocols.py | 154 ------------------------- src/plopp/core/typing.py | 120 ++++++++++++++++++- src/plopp/graphics/imageview.py | 3 +- src/plopp/graphics/lineview.py | 3 +- src/plopp/graphics/scatter3dview.py | 3 +- src/plopp/graphics/scatterview.py | 3 +- src/plopp/plotting/plot.py | 4 +- src/plopp/plotting/scatter.py | 4 +- src/plopp/plotting/scatter3d.py | 4 +- src/plopp/plotting/slicer.py | 4 +- src/plopp/plotting/superplot.py | 4 +- src/plopp/plotting/xyplot.py | 3 +- 14 files changed, 143 insertions(+), 178 deletions(-) delete mode 100644 src/plopp/backends/protocols.py diff --git a/src/plopp/backends/matplotlib/tiled.py b/src/plopp/backends/matplotlib/tiled.py index 86108c60..e5892c84 100644 --- a/src/plopp/backends/matplotlib/tiled.py +++ b/src/plopp/backends/matplotlib/tiled.py @@ -8,7 +8,7 @@ import numpy as np from matplotlib import gridspec -from ..protocols import FigureLike +from ...core.typing import FigureLike from .static import get_repr_maker from .utils import copy_figure, is_interactive_backend, make_figure @@ -73,9 +73,11 @@ def __init__( self.nrows = nrows self.ncols = ncols self.fig = make_figure( - figsize=(min(6.0 * ncols, 15.0), min(4.0 * nrows, 15.0)) - if figsize is None - else figsize, + figsize=( + (min(6.0 * ncols, 15.0), min(4.0 * nrows, 15.0)) + if figsize is None + else figsize + ), layout='constrained', ) diff --git a/src/plopp/backends/matplotlib/utils.py b/src/plopp/backends/matplotlib/utils.py index 31d8cd8e..f4abd6c9 100644 --- a/src/plopp/backends/matplotlib/utils.py +++ b/src/plopp/backends/matplotlib/utils.py @@ -7,7 +7,7 @@ import matplotlib as mpl from matplotlib.pyplot import Figure, _get_backend_mod -from ..protocols import FigureLike +from ...core.typing import FigureLike def fig_to_bytes(fig: Figure, form: Literal['png', 'svg'] = 'png') -> bytes: diff --git a/src/plopp/backends/protocols.py b/src/plopp/backends/protocols.py deleted file mode 100644 index 79f5bd8d..00000000 --- a/src/plopp/backends/protocols.py +++ /dev/null @@ -1,154 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause -# Copyright (c) 2023 Scipp contributors (https://github.com/scipp) - -from __future__ import annotations - -from typing import Dict, Protocol, Tuple - -import scipp as sc - -from ..core import Node - - -class CanvasLike(Protocol): - def autoscale(self) -> None: - ... - - def draw(self) -> None: - ... - - def save(self) -> None: - ... - - @property - def empty(self) -> bool: - ... - - @property - def title(self) -> str: - ... - - @title.setter - def title(self, title: str) -> None: - ... - - @property - def xlabel(self) -> str: - ... - - @xlabel.setter - def xlabel(self, xlabel: str) -> None: - ... - - @property - def ylabel(self) -> str: - ... - - @ylabel.setter - def ylabel(self, ylabel: str) -> None: - ... - - @property - def xscale(self) -> str: - ... - - @xscale.setter - def xscale(self, xscale: str) -> None: - ... - - @property - def yscale(self) -> str: - ... - - @yscale.setter - def yscale(self, yscale: str) -> None: - ... - - @property - def xmin(self) -> float: - ... - - @xmin.setter - def xmin(self, xmin: float) -> None: - ... - - @property - def xmax(self) -> float: - ... - - @xmax.setter - def xmax(self, xmax: float) -> None: - ... - - @property - def ymin(self) -> float: - ... - - @ymin.setter - def ymin(self, ymin: float) -> None: - ... - - @property - def ymax(self) -> float: - ... - - @ymax.setter - def ymax(self, ymax: float) -> None: - ... - - @property - def xrange(self) -> Tuple[float, float]: - ... - - @xrange.setter - def xrange(self, xrange: Tuple[float, float]) -> None: - ... - - @property - def yrange(self) -> Tuple[float, float]: - ... - - @yrange.setter - def yrange(self, yrange: Tuple[float, float]) -> None: - ... - - def logx(self) -> None: - ... - - def logy(self) -> None: - ... - - -class ArtistLike(Protocol): - def update(self, new_values: sc.DataArray) -> None: - ... - - -class FigureLike(Protocol): - @property - def canvas(self) -> CanvasLike: - ... - - @property - def artists(self) -> Dict[str, ArtistLike]: - ... - - @property - def graph_nodes(self) -> Dict[str, Node]: - ... - - @property - def id(self) -> str: - ... - - def save(self, filename: str, **kwargs) -> None: - ... - - def update(self, *args, **kwargs) -> None: - ... - - def notify_view(self, *args, **kwargs) -> None: - ... - - def copy(self, **kwargs) -> FigureLike: - ... diff --git a/src/plopp/core/typing.py b/src/plopp/core/typing.py index 15abfe67..e3e8d1fb 100644 --- a/src/plopp/core/typing.py +++ b/src/plopp/core/typing.py @@ -1,10 +1,11 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2023 Scipp contributors (https://github.com/scipp) -from typing import Dict, Union +from __future__ import annotations +from typing import Dict, Protocol, Tuple, Union from numpy import ndarray -from scipp.typing import VariableLike +import scipp as sc from .node import Node @@ -19,12 +20,123 @@ class VisibleDeprecationWarning(UserWarning): VisibleDeprecationWarning.__module__ = 'plopp' -Plottable = Union[VariableLike, ndarray, Node] +Plottable = Union[sc.VariableLike, ndarray, Node] PlottableMulti = Union[Plottable, Dict[str, Plottable]] + +class CanvasLike(Protocol): + def autoscale(self) -> None: ... + + def draw(self) -> None: ... + + def save(self) -> None: ... + + @property + def empty(self) -> bool: ... + + @property + def title(self) -> str: ... + + @title.setter + def title(self, title: str) -> None: ... + + @property + def xlabel(self) -> str: ... + + @xlabel.setter + def xlabel(self, xlabel: str) -> None: ... + + @property + def ylabel(self) -> str: ... + + @ylabel.setter + def ylabel(self, ylabel: str) -> None: ... + + @property + def xscale(self) -> str: ... + + @xscale.setter + def xscale(self, xscale: str) -> None: ... + + @property + def yscale(self) -> str: ... + + @yscale.setter + def yscale(self, yscale: str) -> None: ... + + @property + def xmin(self) -> float: ... + + @xmin.setter + def xmin(self, xmin: float) -> None: ... + + @property + def xmax(self) -> float: ... + + @xmax.setter + def xmax(self, xmax: float) -> None: ... + + @property + def ymin(self) -> float: ... + + @ymin.setter + def ymin(self, ymin: float) -> None: ... + + @property + def ymax(self) -> float: ... + + @ymax.setter + def ymax(self, ymax: float) -> None: ... + + @property + def xrange(self) -> Tuple[float, float]: ... + + @xrange.setter + def xrange(self, xrange: Tuple[float, float]) -> None: ... + + @property + def yrange(self) -> Tuple[float, float]: ... + + @yrange.setter + def yrange(self, yrange: Tuple[float, float]) -> None: ... + + def logx(self) -> None: ... + + def logy(self) -> None: ... + + +class ArtistLike(Protocol): + def update(self, new_values: sc.DataArray) -> None: ... + + +class FigureLike(Protocol): + @property + def canvas(self) -> CanvasLike: ... + + @property + def artists(self) -> Dict[str, ArtistLike]: ... + + @property + def graph_nodes(self) -> Dict[str, Node]: ... + + @property + def id(self) -> str: ... + + def save(self, filename: str, **kwargs) -> None: ... + + def update(self, *args, **kwargs) -> None: ... + + def notify_view(self, *args, **kwargs) -> None: ... + + def copy(self, **kwargs) -> FigureLike: ... + + __all__ = [ + 'VisibleDeprecationWarning', 'Plottable', 'PlottableMulti', - 'VisibleDeprecationWarning', + 'CanvasLike', + 'ArtistLike', + 'FigureLike', ] diff --git a/src/plopp/graphics/imageview.py b/src/plopp/graphics/imageview.py index a23922f2..751a31f8 100644 --- a/src/plopp/graphics/imageview.py +++ b/src/plopp/graphics/imageview.py @@ -6,6 +6,7 @@ import scipp as sc from .. import backends +from ..core.typing import FigureLike from .colormapper import ColorMapper from .graphicalview import GraphicalView @@ -114,7 +115,7 @@ def make_artist(self, new_values): return backends.image(canvas=self.canvas, data=new_values, **self._kwargs) -def imagefigure(*args, **kwargs): +def imagefigure(*args, **kwargs) -> FigureLike: """ Create a figure to represent two-dimensional data from one or more graph node(s). diff --git a/src/plopp/graphics/lineview.py b/src/plopp/graphics/lineview.py index 7f55da33..6c729c01 100644 --- a/src/plopp/graphics/lineview.py +++ b/src/plopp/graphics/lineview.py @@ -6,6 +6,7 @@ import scipp as sc from .. import backends +from ..core.typing import FigureLike from .graphicalview import GraphicalView @@ -117,7 +118,7 @@ def make_artist(self, new_values): ) -def linefigure(*args, **kwargs): +def linefigure(*args, **kwargs) -> FigureLike: """ Create a figure to represent one-dimensional data from one or more graph node(s). diff --git a/src/plopp/graphics/scatter3dview.py b/src/plopp/graphics/scatter3dview.py index 5c95483a..bf5a792c 100644 --- a/src/plopp/graphics/scatter3dview.py +++ b/src/plopp/graphics/scatter3dview.py @@ -7,6 +7,7 @@ from .. import backends from ..core import View +from ..core.typing import FigureLike from ..core.utils import make_compatible from .camera import Camera from .colormapper import ColorMapper @@ -187,7 +188,7 @@ def remove(self, key: str): del self.artists[key] -def scatter3dfigure(*args, **kwargs): +def scatter3dfigure(*args, **kwargs) -> FigureLike: """ Create a figure to represent three-dimensional data from one or more graph node(s). diff --git a/src/plopp/graphics/scatterview.py b/src/plopp/graphics/scatterview.py index ee541715..948ef474 100644 --- a/src/plopp/graphics/scatterview.py +++ b/src/plopp/graphics/scatterview.py @@ -6,6 +6,7 @@ import scipp as sc from .. import backends +from ..core.typing import FigureLike from .colormapper import ColorMapper from .graphicalview import GraphicalView @@ -89,7 +90,7 @@ def make_artist(self, new_values): ) -def scatterfigure(*args, **kwargs): +def scatterfigure(*args, **kwargs) -> FigureLike: """ Create a figure to represent scatter data from one or more graph node(s). diff --git a/src/plopp/plotting/plot.py b/src/plopp/plotting/plot.py index b77b5a5d..84940753 100644 --- a/src/plopp/plotting/plot.py +++ b/src/plopp/plotting/plot.py @@ -6,7 +6,7 @@ from scipp import Variable -from ..core.typing import PlottableMulti +from ..core.typing import FigureLike, PlottableMulti from ..graphics import imagefigure, linefigure from .common import input_to_nodes, preprocess, raise_multiple_inputs_for_2d_plot_error @@ -30,7 +30,7 @@ def plot( autoscale: Literal['auto', 'grow'] = 'auto', legend: Union[bool, Tuple[float, float]] = True, **kwargs, -): +) -> FigureLike: """Plot a Scipp object. Parameters diff --git a/src/plopp/plotting/scatter.py b/src/plopp/plotting/scatter.py index dc46b6d9..3f4dea09 100644 --- a/src/plopp/plotting/scatter.py +++ b/src/plopp/plotting/scatter.py @@ -7,7 +7,7 @@ import scipp as sc -from ..core.typing import PlottableMulti +from ..core.typing import FigureLike, PlottableMulti from .common import check_not_binned, from_compatible_lib, input_to_nodes @@ -47,7 +47,7 @@ def scatter( cbar: bool = False, cmap: str = 'viridis', **kwargs, -): +) -> FigureLike: """ Make a two-dimensional scatter plot. diff --git a/src/plopp/plotting/scatter3d.py b/src/plopp/plotting/scatter3d.py index 1570e3e3..f82b9593 100644 --- a/src/plopp/plotting/scatter3d.py +++ b/src/plopp/plotting/scatter3d.py @@ -7,7 +7,7 @@ import scipp as sc -from ..core.typing import PlottableMulti +from ..core.typing import FigureLike, PlottableMulti from ..graphics import Camera from .common import check_not_binned, from_compatible_lib, input_to_nodes @@ -51,7 +51,7 @@ def scatter3d( cmap: str = 'viridis', camera: Optional[Camera] = None, **kwargs, -): +) -> FigureLike: """Make a three-dimensional scatter plot. To specify the positions of the scatter points, you can use: diff --git a/src/plopp/plotting/slicer.py b/src/plopp/plotting/slicer.py index 6f8faea0..42c7df8d 100644 --- a/src/plopp/plotting/slicer.py +++ b/src/plopp/plotting/slicer.py @@ -9,7 +9,7 @@ from scipp.typing import VariableLike from ..core import widget_node -from ..core.typing import PlottableMulti +from ..core.typing import FigureLike, PlottableMulti from ..graphics import imagefigure, linefigure from .common import ( input_to_nodes, @@ -151,7 +151,7 @@ def slicer( vmin: Union[VariableLike, int, float] = None, vmax: Union[VariableLike, int, float] = None, **kwargs, -): +) -> FigureLike: """ Plot a multi-dimensional object by slicing one or more of the dimensions. This will produce one slider per sliced dimension, below the figure. diff --git a/src/plopp/plotting/superplot.py b/src/plopp/plotting/superplot.py index 8df79fe7..3812bb12 100644 --- a/src/plopp/plotting/superplot.py +++ b/src/plopp/plotting/superplot.py @@ -3,7 +3,7 @@ from typing import Optional -from ..core.typing import Plottable +from ..core.typing import FigureLike, Plottable from .common import require_interactive_backend from .slicer import Slicer @@ -12,7 +12,7 @@ def superplot( obj: Plottable, keep: Optional[str] = None, **kwargs, -): +) -> FigureLike: """ Plot a multi-dimensional object as a one-dimensional line, slicing all but one dimension. This will produce one slider per sliced dimension, below the figure. diff --git a/src/plopp/plotting/xyplot.py b/src/plopp/plotting/xyplot.py index ef6c58ec..8d47de4b 100644 --- a/src/plopp/plotting/xyplot.py +++ b/src/plopp/plotting/xyplot.py @@ -7,6 +7,7 @@ from numpy import ndarray from ..core import Node +from ..core.typing import FigureLike from ..graphics import linefigure from .common import to_variable @@ -30,7 +31,7 @@ def xyplot( x: Union[sc.Variable, ndarray, list, Node], y: Union[sc.Variable, ndarray, list, Node], **kwargs, -): +) -> FigureLike: """ Make a one-dimensional plot of one variable ``y`` as a function of another ``x``. From d4dac250ac609f52f026e4db3ae413cf2b791364 Mon Sep 17 00:00:00 2001 From: Neil Vaytet Date: Wed, 17 Apr 2024 15:03:16 +0200 Subject: [PATCH 2/3] formatting --- src/plopp/core/typing.py | 114 ++++++++++++++++++++++++++------------- 1 file changed, 76 insertions(+), 38 deletions(-) diff --git a/src/plopp/core/typing.py b/src/plopp/core/typing.py index e3e8d1fb..bdfded6a 100644 --- a/src/plopp/core/typing.py +++ b/src/plopp/core/typing.py @@ -4,8 +4,9 @@ from __future__ import annotations from typing import Dict, Protocol, Tuple, Union -from numpy import ndarray + import scipp as sc +from numpy import ndarray from .node import Node @@ -26,110 +27,147 @@ class VisibleDeprecationWarning(UserWarning): class CanvasLike(Protocol): - def autoscale(self) -> None: ... + def autoscale(self) -> None: + ... - def draw(self) -> None: ... + def draw(self) -> None: + ... - def save(self) -> None: ... + def save(self) -> None: + ... @property - def empty(self) -> bool: ... + def empty(self) -> bool: + ... @property - def title(self) -> str: ... + def title(self) -> str: + ... @title.setter - def title(self, title: str) -> None: ... + def title(self, title: str) -> None: + ... @property - def xlabel(self) -> str: ... + def xlabel(self) -> str: + ... @xlabel.setter - def xlabel(self, xlabel: str) -> None: ... + def xlabel(self, xlabel: str) -> None: + ... @property - def ylabel(self) -> str: ... + def ylabel(self) -> str: + ... @ylabel.setter - def ylabel(self, ylabel: str) -> None: ... + def ylabel(self, ylabel: str) -> None: + ... @property - def xscale(self) -> str: ... + def xscale(self) -> str: + ... @xscale.setter - def xscale(self, xscale: str) -> None: ... + def xscale(self, xscale: str) -> None: + ... @property - def yscale(self) -> str: ... + def yscale(self) -> str: + ... @yscale.setter - def yscale(self, yscale: str) -> None: ... + def yscale(self, yscale: str) -> None: + ... @property - def xmin(self) -> float: ... + def xmin(self) -> float: + ... @xmin.setter - def xmin(self, xmin: float) -> None: ... + def xmin(self, xmin: float) -> None: + ... @property - def xmax(self) -> float: ... + def xmax(self) -> float: + ... @xmax.setter - def xmax(self, xmax: float) -> None: ... + def xmax(self, xmax: float) -> None: + ... @property - def ymin(self) -> float: ... + def ymin(self) -> float: + ... @ymin.setter - def ymin(self, ymin: float) -> None: ... + def ymin(self, ymin: float) -> None: + ... @property - def ymax(self) -> float: ... + def ymax(self) -> float: + ... @ymax.setter - def ymax(self, ymax: float) -> None: ... + def ymax(self, ymax: float) -> None: + ... @property - def xrange(self) -> Tuple[float, float]: ... + def xrange(self) -> Tuple[float, float]: + ... @xrange.setter - def xrange(self, xrange: Tuple[float, float]) -> None: ... + def xrange(self, xrange: Tuple[float, float]) -> None: + ... @property - def yrange(self) -> Tuple[float, float]: ... + def yrange(self) -> Tuple[float, float]: + ... @yrange.setter - def yrange(self, yrange: Tuple[float, float]) -> None: ... + def yrange(self, yrange: Tuple[float, float]) -> None: + ... - def logx(self) -> None: ... + def logx(self) -> None: + ... - def logy(self) -> None: ... + def logy(self) -> None: + ... class ArtistLike(Protocol): - def update(self, new_values: sc.DataArray) -> None: ... + def update(self, new_values: sc.DataArray) -> None: + ... class FigureLike(Protocol): @property - def canvas(self) -> CanvasLike: ... + def canvas(self) -> CanvasLike: + ... @property - def artists(self) -> Dict[str, ArtistLike]: ... + def artists(self) -> Dict[str, ArtistLike]: + ... @property - def graph_nodes(self) -> Dict[str, Node]: ... + def graph_nodes(self) -> Dict[str, Node]: + ... @property - def id(self) -> str: ... + def id(self) -> str: + ... - def save(self, filename: str, **kwargs) -> None: ... + def save(self, filename: str, **kwargs) -> None: + ... - def update(self, *args, **kwargs) -> None: ... + def update(self, *args, **kwargs) -> None: + ... - def notify_view(self, *args, **kwargs) -> None: ... + def notify_view(self, *args, **kwargs) -> None: + ... - def copy(self, **kwargs) -> FigureLike: ... + def copy(self, **kwargs) -> FigureLike: + ... __all__ = [ From ff7348f8dd4146f1e3c5738cc16b33b302d30364 Mon Sep 17 00:00:00 2001 From: Neil Vaytet Date: Wed, 17 Apr 2024 15:17:15 +0200 Subject: [PATCH 3/3] fix imports --- src/plopp/core/typing.py | 3 ++- src/plopp/widgets/drawing.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plopp/core/typing.py b/src/plopp/core/typing.py index bdfded6a..d81d1f18 100644 --- a/src/plopp/core/typing.py +++ b/src/plopp/core/typing.py @@ -7,6 +7,7 @@ import scipp as sc from numpy import ndarray +from scipp.typing import VariableLike from .node import Node @@ -21,7 +22,7 @@ class VisibleDeprecationWarning(UserWarning): VisibleDeprecationWarning.__module__ = 'plopp' -Plottable = Union[sc.VariableLike, ndarray, Node] +Plottable = Union[VariableLike, ndarray, Node] PlottableMulti = Union[Plottable, Dict[str, Plottable]] diff --git a/src/plopp/widgets/drawing.py b/src/plopp/widgets/drawing.py index 531c1aa1..2314edb3 100644 --- a/src/plopp/widgets/drawing.py +++ b/src/plopp/widgets/drawing.py @@ -6,8 +6,8 @@ import scipp as sc -from ..backends.protocols import FigureLike from ..core import Node, node +from ..core.typing import FigureLike from .tools import ToggleTool