Source code for plotpy.styles.shape

# -*- coding: utf-8 -*-

from __future__ import annotations

from typing import TYPE_CHECKING

import numpy as np
from guidata.dataset import (
    BeginGroup,
    BeginTabGroup,
    BoolItem,
    ColorItem,
    DataSet,
    EndGroup,
    EndTabGroup,
    FloatArrayItem,
    FloatItem,
    GetAttrProp,
    ImageChoiceItem,
    IntItem,
    StringItem,
)
from qtpy import QtGui as QG
from qwt import QwtPlotMarker

from plotpy.config import _
from plotpy.styles.base import (
    MARKERSTYLE_CHOICES,
    MARKERSTYLE_NAME,
    MARKERSTYLES,
    BrushStyleItem,
    ItemParameters,
    LineStyleItem,
    SymbolItem,
    TextStyleItem,
)

if TYPE_CHECKING:
    from plotpy.items import AnnotatedShape, Axes, Marker, PolygonShape, XRangeSelection
    from plotpy.plot import BasePlot
    from plotpy.styles import (
        BrushStyleParam,
        LineStyleParam,
        SymbolParam,
        TextStyleParam,
    )


[docs] class MarkerParam(DataSet): """Parameters for a marker item""" _styles = BeginTabGroup("Styles") # ------------------------------------------------------------------ Line tab ___line = BeginGroup(_("Line")).set_prop("display", icon="dashdot.png") line = LineStyleItem(_("Line (not selected)")) sel_line = LineStyleItem(_("Line (selected)")) ___eline = EndGroup(_("Line")) # ---------------------------------------------------------------- Symbol tab ___sym = BeginGroup(_("Symbol")).set_prop("display", icon="diamond.png") symbol = SymbolItem(_("Symbol (not selected)")) sel_symbol = SymbolItem(_("Symbol (selected)")) ___esym = EndGroup(_("Symbol")) # ------------------------------------------------------------------ Text tab ___text = BeginGroup(_("Text")).set_prop("display", icon="font.png") text = TextStyleItem(_("Text (not selected)")) sel_text = TextStyleItem(_("Text (selected)")) ___etext = EndGroup(_("Text")) # ----------------------------------------------------------------------- End _endstyles = EndTabGroup("Styles") markerstyle = ImageChoiceItem( _("Line style"), MARKERSTYLE_CHOICES, default="NoLine" ) spacing = IntItem(_("Spacing"), default=10, min=0)
[docs] def update_param(self, obj: Marker) -> None: """Update parameters from object Args: obj: Marker object """ self.symbol: SymbolParam self.text: TextStyleParam self.line: LineStyleParam self.sel_symbol: SymbolParam self.sel_text: TextStyleParam self.sel_line: LineStyleParam if obj.selected: symbol = self.sel_symbol text = self.sel_text line = self.sel_line else: symbol = self.symbol text = self.text line = self.line symbol.update_param(obj.symbol()) text.update_param(obj.label()) line.update_param(obj.linePen()) self.markerstyle = MARKERSTYLE_NAME[obj.lineStyle()] self.spacing = obj.spacing()
[docs] def update_item(self, item: Marker) -> None: """Update object from parameters Args: item: Marker object """ if item.selected: line = self.sel_line symb = self.sel_symbol text = self.sel_text else: line = self.line symb = self.symbol text = self.text symb.update_symbol(item) label = item.label() text.update_text(label) item.setLabel(label) item.setLinePen(line.build_pen()) item.setLineStyle(getattr(QwtPlotMarker, self.markerstyle)) item.setSpacing(self.spacing) item.update_label()
[docs] def set_markerstyle(self, style: None | str | int) -> None: """Set marker line style Args: style: line style. It can be one of the following: * convenient values: '+', '-', '|' or None * `QwtPlotMarker.NoLine`, `QwtPlotMarker.Vertical`, ... """ self.markerstyle = MARKERSTYLES.get(style, style)
[docs] class ShapeParam(DataSet): """Parameters for a shape item""" label = StringItem(_("Title"), default="") _styles = BeginTabGroup("Styles") # ------------------------------------------------------------------ Line tab ___line = BeginGroup(_("Line")).set_prop("display", icon="dashdot.png") line = LineStyleItem(_("Line (not selected)")) sel_line = LineStyleItem(_("Line (selected)")) ___eline = EndGroup(_("Line")) # ---------------------------------------------------------------- Symbol tab ___sym = BeginGroup(_("Symbol")).set_prop("display", icon="diamond.png") symbol = SymbolItem(_("Symbol (not selected)")) sel_symbol = SymbolItem(_("Symbol (selected)")) ___esym = EndGroup(_("Symbol")) # ------------------------------------------------------------------ Fill tab ___fill = BeginGroup(_("Fill pattern")).set_prop( "display", icon="dense6pattern.png" ) fill = BrushStyleItem(_("Fill pattern (not selected)")) sel_fill = BrushStyleItem(_("Fill pattern (selected)")) ___efill = EndGroup(_("Fill pattern")) # ----------------------------------------------------------------------- End _endstyles = EndTabGroup("Styles") readonly = BoolItem( _("Read-only shape"), default=False, help=_("Read-only shapes can't be removed from the item list panel"), ) private = BoolItem( _("Private shape"), default=False, help=_("Private shapes are not shown in the item list panel"), ).set_pos(col=1)
[docs] def update_param(self, obj: PolygonShape) -> None: """Update parameters from object Args: obj: Shape object """ self.line: LineStyleParam self.symbol: SymbolParam self.fill: BrushStyleParam self.sel_line: LineStyleParam self.sel_symbol: SymbolParam self.sel_fill: BrushStyleParam self.label = str(obj.title().text()) self.line.update_param(obj.pen) self.symbol.update_param(obj.symbol) self.fill.update_param(obj.brush) self.sel_line.update_param(obj.sel_pen) self.sel_symbol.update_param(obj.sel_symbol) self.sel_fill.update_param(obj.sel_brush) self.readonly = obj.is_readonly() self.private = obj.is_private()
[docs] def update_item(self, item: PolygonShape) -> None: """Update object from parameters Args: item: Shape object """ plot: BasePlot = item.plot() if plot is not None: plot.blockSignals(True) # Avoid unwanted calls of update_param # triggered by the setter methods below item.setTitle(self.label) item.pen = self.line.build_pen() item.symbol = self.symbol.build_symbol() item.brush = self.fill.build_brush() item.sel_pen = self.sel_line.build_pen() item.sel_symbol = self.sel_symbol.build_symbol() item.sel_brush = self.sel_fill.build_brush() item.set_readonly(self.readonly) item.set_private(self.private) if plot is not None: plot.blockSignals(False)
[docs] class AxesShapeParam(DataSet): """Parameters for an axes item""" arrow_angle = FloatItem( _("Arrow angle") + " (°)", min=0.0, max=90.0, default=15.0, nonzero=True ) arrow_size = FloatItem( _("Arrow size") + " (%)", min=0.0, max=100.0, default=0.05, nonzero=True ) _styles = BeginTabGroup("Styles") # ------------------------------------------------------------------ Line tab ___line = BeginGroup(_("Line")).set_prop("display", icon="dashdot.png") xarrow_pen = LineStyleItem(_("Line (X-Axis)")) yarrow_pen = LineStyleItem(_("Line (Y-Axis)")) ___eline = EndGroup(_("Line")) # ------------------------------------------------------------------ Fill tab ___fill = BeginGroup(_("Fill pattern")).set_prop( "display", icon="dense6pattern.png" ) xarrow_brush = BrushStyleItem(_("Fill pattern (X-Axis)")) yarrow_brush = BrushStyleItem(_("Fill pattern (Y-Axis)")) ___efill = EndGroup(_("Fill pattern")) # ----------------------------------------------------------------------- End _endstyles = EndTabGroup("Styles")
[docs] def update_param(self, item: Axes) -> None: """Update parameters from object Args: obj: Axes object """ self.xarrow_pen: LineStyleParam self.yarrow_pen: LineStyleParam self.xarrow_brush: BrushStyleParam self.yarrow_brush: BrushStyleParam self.arrow_angle = item.arrow_angle self.arrow_size = item.arrow_size self.xarrow_pen.update_param(item.x_pen) self.yarrow_pen.update_param(item.y_pen) self.xarrow_brush.update_param(item.x_brush) self.yarrow_brush.update_param(item.y_brush)
[docs] def update_item(self, item: Axes) -> None: """Update object from parameters Args: obj: Axes object """ item.arrow_angle = self.arrow_angle item.arrow_size = self.arrow_size item.x_pen = self.xarrow_pen.build_pen() item.x_brush = self.xarrow_brush.build_brush() item.y_pen = self.yarrow_pen.build_pen() item.y_brush = self.yarrow_brush.build_brush()
[docs] class AnnotationParam(DataSet): """Parameters for annotations""" _multiselection = False show_label = BoolItem(_("Show annotation"), default=True) show_computations = BoolItem( _("Show informations on area covered by this shape"), default=True ) show_subtitle = BoolItem(_("Show subtitle"), default=True) title = StringItem(_("Title"), default="").set_prop( "display", hide=GetAttrProp("_multiselection") ) subtitle = StringItem(_("Subtitle"), default="").set_prop( "display", hide=GetAttrProp("_multiselection") ) format = StringItem(_("String formatting"), default="%.1f") uncertainty = FloatItem( _("Uncertainty"), default=0.0, min=0.0, max=1.0, help=_("Measurement relative uncertainty"), ).set_pos(col=1) transform_matrix = FloatArrayItem( _("Transform matrix"), default=np.eye(3, dtype=float) ) readonly = BoolItem( _("Read-only shape"), default=False, help=_("Read-only shapes can't be removed from the item list panel"), ) private = BoolItem( _("Private shape"), default=False, help=_("Private shapes are not shown in the item list panel"), ).set_pos(col=1)
[docs] def update_param(self, obj: AnnotatedShape) -> None: """Update parameters from object Args: obj: AnnotatedShape object """ self.show_label = obj.is_label_visible() self.show_computations = obj.area_computations_visible self.show_subtitle = obj.subtitle_visible self.title = str(obj.title().text()) self.readonly = obj.is_readonly() self.private = obj.is_private()
[docs] def update_item(self, item: AnnotatedShape) -> None: """Update object from parameters Args: obj: AnnotatedShape object """ plot: BasePlot = item.plot() if plot is not None: plot.blockSignals(True) # Avoid unwanted calls of update_param # triggered by the setter methods below item.setTitle(self.title) item.set_label_visible(self.show_label) item.area_computations_visible = self.show_computations item.subtitle_visible = self.show_subtitle item.update_label() item.set_readonly(self.readonly) item.set_private(self.private) if plot is not None: plot.blockSignals(False)
class AnnotationParam_MS(AnnotationParam): """Parameters for annotations with multi-selection enabled""" _multiselection = True ItemParameters.register_multiselection(AnnotationParam, AnnotationParam_MS)
[docs] class RangeShapeParam(DataSet): """Parameters for a range selection item""" label = StringItem(_("Title"), default="") _styles = BeginTabGroup("Styles") # ------------------------------------------------------------------ Line tab ___line = BeginGroup(_("Line")).set_prop("display", icon="dashdot.png") line = LineStyleItem(_("Line (not selected)")) sel_line = LineStyleItem(_("Line (selected)")) ___eline = EndGroup(_("Line")) # ---------------------------------------------------------------- Symbol tab ___symbol = BeginGroup(_("Symbol")).set_prop("display", icon="diamond.png") symbol = SymbolItem(_("Symbol (not selected)")) sel_symbol = SymbolItem(_("Symbol (selected)")) ___esymbol = EndGroup(_("Symbol")) # ------------------------------------------------------------------ Fill tab ___fill = BeginGroup(_("Fill")).set_prop("display", icon="dense6pattern.png") fill = ColorItem(_("Fill color")) shade = FloatItem(_("Shade"), default=0.05, min=0, max=1) ___efill = EndGroup(_("Fill")) # ----------------------------------------------------------------------- End _endstyles = EndTabGroup("Styles")
[docs] def update_param(self, obj: XRangeSelection) -> None: """Update parameters from object Args: obj: XRangeSelection object """ self.label = str(obj.title().text()) self.line: LineStyleParam self.sel_line: LineStyleParam self.symbol: SymbolParam self.sel_symbol: SymbolParam self.line.update_param(obj.pen) self.sel_line.update_param(obj.sel_pen) self.fill = obj.brush.color().name() self.shade = obj.brush.color().alphaF() self.symbol.update_param(obj.symbol) self.sel_symbol.update_param(obj.sel_symbol)
[docs] def update_item(self, item: XRangeSelection) -> None: """Update object from parameters Args: range: XRangeSelection object """ item.setTitle(self.label) item.pen = self.line.build_pen() item.sel_pen = self.sel_line.build_pen() col = QG.QColor(self.fill) col.setAlphaF(self.shade) item.brush = QG.QBrush(col) item.symbol = self.symbol.build_symbol() item.sel_symbol = self.sel_symbol.build_symbol()