Source code for whitecanvas.backend.pyqtgraph.line

from __future__ import annotations
from functools import reduce
import numpy as np
from numpy.typing import NDArray

from qtpy import QtGui, QtCore
import pyqtgraph as pg
from whitecanvas.protocols import LineProtocol, MultiLineProtocol, check_protocol
from whitecanvas.types import LineStyle
from whitecanvas.backend.pyqtgraph._base import PyQtLayer
from ._qt_utils import array_to_qcolor, from_qt_line_style, to_qt_line_style


[docs]@check_protocol(LineProtocol) class MonoLine(pg.PlotCurveItem, PyQtLayer): def __init__(self, xdata, ydata): pen = QtGui.QPen(QtGui.QColor(0, 0, 0)) pen.setCosmetic(True) super().__init__(xdata, ydata, pen=pen, antialias=False) ##### XYDataProtocol ##### def _plt_get_data(self): return self.getData() def _plt_set_data(self, xdata, ydata): self.setData(xdata, ydata) ##### HasEdges ##### def _get_pen(self) -> QtGui.QPen: return self.opts["pen"] def _plt_get_edge_width(self) -> float: return self._get_pen().widthF() def _plt_set_edge_width(self, width: float): pen = self._get_pen() pen.setWidthF(width) self.setPen(pen) def _plt_get_edge_style(self) -> LineStyle: return from_qt_line_style(self._get_pen().style()) def _plt_set_edge_style(self, style: LineStyle): pen = self._get_pen() pen.setStyle(to_qt_line_style(style)) self.setPen(pen) def _plt_get_edge_color(self) -> NDArray[np.float32]: return np.array(self._get_pen().color().getRgbF()) def _plt_set_edge_color(self, color: NDArray[np.float32]): pen = self._get_pen() pen.setColor(array_to_qcolor(color)) self.setPen(pen) def _plt_get_antialias(self) -> bool: return self.opts["antialias"] def _plt_set_antialias(self, antialias: bool): self.opts["antialias"] = antialias self.update()
[docs]@check_protocol(MultiLineProtocol) class MultiLine(pg.ItemGroup, PyQtLayer): def __init__(self, data: list[NDArray[np.floating]]): super().__init__() pen = QtGui.QPen(QtGui.QColor(255, 255, 255)) pen.setCosmetic(True) self._lines: list[pg.PlotCurveItem] = [] for seg in data: item = pg.PlotCurveItem(seg[:, 0], seg[:, 1], pen=pen, antialias=True) self.addItem(item) self._lines.append(item) self._qpen = pen self._data = data self._bounding_rect_cache = None self._antialias = True
[docs] def boundingRect(self): if self._bounding_rect_cache is not None: return self._bounding_rect_cache if len(self._lines) == 0: return QtCore.QRectF() rect = reduce(lambda a, b: a | b, (item.boundingRect() for item in self._lines)) self._bounding_rect_cache = rect return rect
##### XYDataProtocol ##### def _plt_get_data(self): return self._data def _plt_set_data(self, data: list[NDArray[np.floating]]): ndata = len(data) nitem = len(self._lines) scene = self.scene() if ndata < nitem: for item in self._lines[ndata:]: scene.removeItem(item) self._lines = self._lines[:ndata] else: pen = self._qpen for _ in range(ndata - nitem): item = pg.PlotCurveItem(pen=pen, antialias=True) self.addItem(item) self._lines.append(item) for item, seg in zip(self._lines, data): item.setData(seg[:, 0], seg[:, 1]) self._bounding_rect_cache = None ##### HasEdges ##### def _set_pen_to_curves(self): for item in self._lines: item.setPen(self._qpen) def _plt_get_edge_width(self) -> float: return self._qpen.widthF() def _plt_set_edge_width(self, width: float): self._qpen.setWidthF(width) self._set_pen_to_curves() def _plt_get_edge_style(self) -> LineStyle: return from_qt_line_style(self._qpen.style()) def _plt_set_edge_style(self, style: LineStyle): self._qpen.setStyle(to_qt_line_style(style)) self._set_pen_to_curves() def _plt_get_edge_color(self) -> NDArray[np.float32]: return np.array(self._qpen.color().getRgbF()) def _plt_set_edge_color(self, color: NDArray[np.float32]): self._qpen.setColor(array_to_qcolor(color)) self._set_pen_to_curves() def _plt_get_antialias(self) -> bool: return self._antialias def _plt_set_antialias(self, antialias: bool): for item in self._lines: item.opts["antialias"] = antialias item.update() self._antialias = antialias