Source code for plotpy.styles.axes

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

from __future__ import annotations

from typing import TYPE_CHECKING

from guidata.dataset import (
    BeginGroup,
    ChoiceItem,
    ColorItem,
    DataSet,
    EndGroup,
    FloatItem,
    ObjectItem,
    StringItem,
)
from guidata.dataset.qtitemwidgets import DataSetWidget
from guidata.dataset.qtwidgets import DataSetEditLayout
from qwt import QwtPlot

from plotpy.config import _
from plotpy.constants import X_BOTTOM, Y_LEFT, Y_RIGHT
from plotpy.styles.base import FontItem

if TYPE_CHECKING:
    from qwt import QwtPlotItem, QwtScaleDiv

    from plotpy.items import BaseImageItem
    from plotpy.plot import BasePlot


class AxeStyleParam(DataSet):
    """Style parameters for an axis."""

    title = StringItem(_("Title"), default="")
    unit = StringItem(_("Unit"), default="")
    color = ColorItem(_("Color"), default="black").set_pos(col=1)
    title_font = FontItem(_("Title font"))
    ticks_font = FontItem(_("Values font"))


class AxisParam(DataSet):
    """Scale parameters for an axis."""

    scale = ChoiceItem(
        _("Scale"),
        [("lin", _("linear")), ("log", _("logarithmic")), ("datetime", _("date/time"))],
        default="lin",
    )
    autoscale = ChoiceItem(
        _("Autoscale strategy"),
        [
            ("auto", _("Auto")),
            ("fixed", _("Fixed range")),
            ("none", _("Disabled")),
        ],
        default="auto",
        help=_(
            "Strategy used by the AutoScale action for this axis: "
            "'Auto' computes bounds from items, 'Fixed range' applies the "
            "Min/Max values defined above, 'Disabled' leaves the axis untouched."
        ),
    )
    vmin = FloatItem("Min", help=_("Lower axis limit"), default=0.0)
    vmax = FloatItem("Max", help=_("Upper axis limit"), default=1.0)

    def update_param(self, plot: BasePlot, axis_id: int) -> None:
        """
        Update the parameters of the axis.

        Args:
            plot: The plot from which to update the parameters.
            axis_id: The axis ID to update.
        """
        self.scale = plot.get_axis_scale(axis_id)
        axis: QwtScaleDiv = plot.axisScaleDiv(axis_id)
        self.vmin = axis.lowerBound()
        self.vmax = axis.upperBound()
        strategy, fixed_vmin, fixed_vmax = plot.get_axis_autoscale_strategy(axis_id)
        self.autoscale = strategy
        if strategy == "fixed":
            if fixed_vmin is not None:
                self.vmin = fixed_vmin
            if fixed_vmax is not None:
                self.vmax = fixed_vmax

    def update_axis(self, plot: BasePlot, axis_id: int) -> None:
        """
        Update the axis with the parameters.

        Args:
            plot: The plot to update.
            axis_id: The axis ID to update.
        """
        plot.enableAxis(axis_id, True)
        plot.set_axis_scale(axis_id, self.scale, autoscale=False)
        plot.setAxisScale(axis_id, self.vmin, self.vmax)
        plot.set_axis_autoscale_strategy(
            axis_id, self.autoscale, vmin=self.vmin, vmax=self.vmax
        )
        plot.disable_unused_axes()
        plot.SIG_AXIS_PARAMETERS_CHANGED.emit(axis_id)


class AxisItemWidget(DataSetWidget):
    """Widget for the axis item."""

    klass = AxisParam


class AxisItem(ObjectItem):
    """Item for an axis."""

    klass = AxisParam


DataSetEditLayout.register(AxisItem, AxisItemWidget)


[docs] class AxesParam(DataSet): """Parameters for the axes of a plot.""" xaxis_id = ChoiceItem( _("X-axis position"), [(QwtPlot.xBottom, _("bottom")), (QwtPlot.xTop, _("top"))], default=QwtPlot.xBottom, ) xaxis = AxisItem(_("X Axis")) yaxis_id = ChoiceItem( _("Y-axis position"), [(QwtPlot.yLeft, _("left")), (QwtPlot.yRight, _("right"))], default=QwtPlot.yLeft, ) yaxis = AxisItem(_("Y Axis"))
[docs] def update_param(self, item: QwtPlotItem) -> None: """ Update the parameters of the axes. Args: item: The plot item from which to update the parameters. """ plot: BasePlot = item.plot() self.xaxis: AxisParam self.yaxis: AxisParam self.xaxis_id = item.xAxis() self.xaxis.update_param(plot, self.xaxis_id) self.yaxis_id = item.yAxis() self.yaxis.update_param(plot, self.yaxis_id)
[docs] def update_item(self, item: QwtPlotItem) -> None: """ Update the axes with the parameters. Args: item: The plot item to update. """ plot: BasePlot = item.plot() self.xaxis: AxisParam self.yaxis: AxisParam plot.grid.setAxes(self.xaxis_id, self.yaxis_id) item.setXAxis(self.xaxis_id) self.xaxis.update_axis(plot, self.xaxis_id) item.setYAxis(self.yaxis_id) self.yaxis.update_axis(plot, self.yaxis_id)
[docs] class ImageAxesParam(DataSet): """Parameters for the axes of an image plot.""" xparams = BeginGroup(_("X Axis")) xmin = FloatItem("x|min", help=_("Lower x-axis limit")) xmax = FloatItem("x|max", help=_("Upper x-axis limit")) _xparams = EndGroup("end X") yparams = BeginGroup(_("Y Axis")) ymin = FloatItem("y|min", help=_("Lower y-axis limit")) ymax = FloatItem("y|max", help=_("Upper y-axis limit")) _yparams = EndGroup("end Y") zparams = BeginGroup(_("Z Axis")) zmin = FloatItem("z|min", help=_("Lower z-axis limit")) zmax = FloatItem("z|max", help=_("Upper z-axis limit")) _zparams = EndGroup("end Z")
[docs] def update_param(self, item: BaseImageItem) -> None: """ Update the parameters of the axes associated with the image item. Args: item: The image item from which to update the parameters. """ plot: BasePlot = item.plot() xaxis: QwtScaleDiv = plot.axisScaleDiv(item.xAxis()) self.xmin = xaxis.lowerBound() self.xmax = xaxis.upperBound() yaxis: QwtScaleDiv = plot.axisScaleDiv(item.yAxis()) self.ymin = yaxis.lowerBound() self.ymax = yaxis.upperBound() self.zmin, self.zmax = item.min, item.max
[docs] def update_item(self, item: BaseImageItem) -> None: """ Update the axes with the parameters associated with the image item. Args: item: The image item to update. """ plot: BasePlot = item.plot() plot.set_plot_limits(self.xmin, self.xmax, self.ymin, self.ymax) item.set_lut_range([self.zmin, self.zmax]) plot.update_colormap_axis(item) for axis_id in (X_BOTTOM, Y_LEFT, Y_RIGHT): plot.SIG_AXIS_PARAMETERS_CHANGED.emit(axis_id)