Draft 'step' curve; couldn't get pg builtin to work

fast_step_curve
Tyler Goodlet 2021-09-17 16:01:28 -04:00
parent 61f3ce43b3
commit 4cf51ffb1e
1 changed files with 51 additions and 14 deletions

View File

@ -20,6 +20,7 @@ Fast, smooth, sexy curves.
""" """
from typing import Tuple from typing import Tuple
import numpy as np
import pyqtgraph as pg import pyqtgraph as pg
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtGui, QtWidgets
@ -29,7 +30,12 @@ from .._profile import pg_profile_enabled
# TODO: got a feeling that dropping this inheritance gets us even more speedups # TODO: got a feeling that dropping this inheritance gets us even more speedups
class FastAppendCurve(pg.PlotCurveItem): class FastAppendCurve(pg.PlotCurveItem):
def __init__(self, *args, **kwargs): def __init__(
self,
*args,
step_mode: bool = False,
**kwargs
) -> None:
# TODO: we can probably just dispense with the parent since # TODO: we can probably just dispense with the parent since
# we're basically only using the pen setting now... # we're basically only using the pen setting now...
@ -37,6 +43,7 @@ class FastAppendCurve(pg.PlotCurveItem):
self._last_line: QtCore.QLineF = None self._last_line: QtCore.QLineF = None
self._xrange: Tuple[int, int] = self.dataBounds(ax=0) self._xrange: Tuple[int, int] = self.dataBounds(ax=0)
self._step_mode: bool = step_mode
# TODO: one question still remaining is if this makes trasform # TODO: one question still remaining is if this makes trasform
# interactions slower (such as zooming) and if so maybe if/when # interactions slower (such as zooming) and if so maybe if/when
@ -59,23 +66,53 @@ class FastAppendCurve(pg.PlotCurveItem):
prepend_length = istart - x[0] prepend_length = istart - x[0]
append_length = x[-1] - istop append_length = x[-1] - istop
# TODO: step mode support # step mode: draw flat top discrete "step"
# if self.stepMode in ("center", True): ## support True for back-compat # over the index space for each datum.
# x2 = np.empty((len(x),2), dtype=x.dtype) if self._step_mode:
# x2[:] = x[:, np.newaxis] y_out = y.copy()
x_out = x.copy()
x2 = np.empty(
# the data + 2 endpoints on either end for
# "termination of the path".
(len(x) + 1, 2),
# we want to align with OHLC or other sampling style
# bars likely so we need fractinal values
dtype=float,
)
x2[0] = x[0] - 0.5
x2[1] = x[0] + 0.5
x2[1:] = x[:, np.newaxis] + 0.5
# flatten to 1-d
x_out = x2.reshape(x2.size)
# we create a 1d with 2 extra indexes to
# hold the start and (current) end value for the steps
# on either end
y_out = np.empty(
2*len(y) + 2,
dtype=y.dtype
)
y2 = np.empty((len(y), 2), dtype=y.dtype)
y2[:] = y[:,np.newaxis]
# flatten
y_out[1:-1] = y2.reshape(y2.size)
y_out[0] = 0
y_out[-1] = 0
# TODO: see ``painter.fillPath()`` call
# inside parent's ``.paint()`` to get
# a solid brush under the curve.
else:
# by default we only pull data up to the last (current) index
x_out, y_out = x[:-1], y[:-1]
# ## If we have a fill level, add two extra points at either end
# x = x2.reshape(x2.size)
# y2 = np.empty((len(y)+2,2), dtype=y.dtype)
# y2[1:-1] = y[:,np.newaxis]
# y = y2.reshape(y2.size)[1:-1]
# y[0] = self.opts['fillLevel']
# y[-1] = self.opts['fillLevel']
if self.path is None or prepend_length: if self.path is None or prepend_length:
self.path = pg.functions.arrayToQPath( self.path = pg.functions.arrayToQPath(
x[:-1], x_out,
y[:-1], y_out,
connect='all' connect='all'
) )
profiler('generate fresh path') profiler('generate fresh path')