Source code for whitecanvas.backend.pyqtgraph.bars

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

from qtpy import QtGui
import pyqtgraph as pg
from whitecanvas.protocols import BarProtocol, check_protocol
from whitecanvas.types import LineStyle, FacePattern
from whitecanvas.utils.normalize import as_color_array
from whitecanvas.backend.pyqtgraph._base import PyQtLayer
from ._qt_utils import (
    array_to_qcolor,
    from_qt_line_style,
    to_qt_line_style,
    from_qt_brush_style,
    to_qt_brush_style,
)


[docs]@check_protocol(BarProtocol) class Bars(pg.BarGraphItem, PyQtLayer): def __init__(self, xlow, xhigh, ylow, yhigh): pen = QtGui.QPen(QtGui.QColor(0, 0, 0)) pen.setCosmetic(True) ndata = len(xlow) super().__init__( x0=xlow, x1=xhigh, y0=ylow, y1=yhigh, pens=[QtGui.QPen(pen) for _ in range(ndata)], brushes=[QtGui.QBrush(QtGui.QColor(0, 0, 0)) for _ in range(ndata)], ) # fmt: skip ##### XYDataProtocol ##### def _plt_get_data(self): return self.opts["x0"], self.opts["x1"], self.opts["y0"], self.opts["y1"] def _plt_set_data(self, xlow, xhigh, ylow, yhigh): self.setOpts(x0=xlow, x1=xhigh, y0=ylow, y1=yhigh) ##### HasFace protocol ##### def _get_brushes(self) -> list[QtGui.QBrush]: return self.opts["brushes"] def _plt_get_face_color(self) -> NDArray[np.float32]: colors = [] for brush in self._get_brushes(): colors.append(brush.color().getRgbF()) return np.array(colors, dtype=np.float32) def _plt_set_face_color(self, color: NDArray[np.float32]): color = as_color_array(color, len(self.opts["x0"])) brushes = self._get_brushes() for brush, c in zip(brushes, color): brush.setColor(array_to_qcolor(c)) self.setOpts(brushes=brushes) def _plt_get_face_pattern(self) -> list[FacePattern]: return [from_qt_brush_style(brush.style()) for brush in self._get_brushes()] def _plt_set_face_pattern(self, pattern: FacePattern | list[FacePattern]): brushes = self._get_brushes() if isinstance(pattern, FacePattern): ptn = to_qt_brush_style(pattern) for brush in brushes: brush.setStyle(ptn) else: for brush, ptn in zip(brushes, pattern): brush.setStyle(to_qt_brush_style(ptn)) self.setOpts(brushes=brushes) ##### HasEdges protocol ##### def _get_pens(self) -> list[QtGui.QPen]: return self.opts["pens"] def _plt_get_edge_color(self) -> NDArray[np.float32]: colors = [] for pen in self._get_pens(): colors.append(pen.color().getRgbF()) return np.array(colors, dtype=np.float32) def _plt_set_edge_color(self, color: NDArray[np.float32]): color = as_color_array(color, len(self.opts["x0"])) pens = self._get_pens() for pen, c in zip(pens, color): pen.setColor(array_to_qcolor(c)) self.setOpts(pens=pens) def _plt_get_edge_width(self) -> float: return np.array([pen.widthF() for pen in self._get_pens()]) def _plt_set_edge_width(self, width: float | NDArray[np.floating]): if np.isscalar(width): width = np.full(len(self.opts["x0"]), width) pens = self._get_pens() for pen, w in zip(pens, width): pen.setWidthF(w) self.setOpts(pens=pens) def _plt_get_edge_style(self) -> LineStyle: return [from_qt_line_style(pen.style()) for pen in self._get_pens()] def _plt_set_edge_style(self, style: LineStyle | list[LineStyle]): pens = self._get_pens() if isinstance(style, LineStyle): style = to_qt_line_style(style) for pen in pens: pen.setStyle(style) else: for pen, s in zip(pens, style): pen.setStyle(to_qt_line_style(s)) self.setOpts(pens=pens)