Add first-draft `PlotItemOverlay.group_maxmin()`
Computes the maxmin values for each underlying plot's in-view range as well as the max up/down swing (in percentage terms) from the plot with most dispersion and returns a all these values plus a `dict` of plots to their ranges as part of output.multichartz
parent
e280e487c8
commit
b1de6dfd0e
|
@ -22,7 +22,6 @@ from collections import defaultdict
|
|||
from functools import partial
|
||||
from typing import (
|
||||
Callable,
|
||||
Optional,
|
||||
)
|
||||
|
||||
from pyqtgraph.graphicsItems.AxisItem import AxisItem
|
||||
|
@ -246,7 +245,7 @@ class ComposedGridLayout:
|
|||
plot: PlotItem,
|
||||
name: str,
|
||||
|
||||
) -> Optional[AxisItem]:
|
||||
) -> AxisItem | None:
|
||||
'''
|
||||
Retrieve the named axis for overlayed ``plot`` or ``None``
|
||||
if axis for that name is not shown.
|
||||
|
@ -321,7 +320,7 @@ class PlotItemOverlay:
|
|||
def add_plotitem(
|
||||
self,
|
||||
plotitem: PlotItem,
|
||||
index: Optional[int] = None,
|
||||
index: int | None = None,
|
||||
|
||||
# event/signal names which will be broadcasted to all added
|
||||
# (relayee) ``PlotItem``s (eg. ``ViewBox.mouseDragEvent``).
|
||||
|
@ -376,7 +375,7 @@ class PlotItemOverlay:
|
|||
|
||||
# TODO: drop this viewbox specific input and
|
||||
# allow a predicate to be passed in by user.
|
||||
axis: 'Optional[int]' = None,
|
||||
axis: int | None = None,
|
||||
|
||||
*,
|
||||
|
||||
|
@ -578,3 +577,93 @@ class PlotItemOverlay:
|
|||
|
||||
# '''
|
||||
# ...
|
||||
|
||||
def group_maxmin(
|
||||
self,
|
||||
focus_around: str | None = None,
|
||||
force_min: float | None = None,
|
||||
|
||||
) -> tuple[
|
||||
float, # mn
|
||||
float, # mx
|
||||
float, # max range in % terms of highest sigma plot's y-range
|
||||
PlotItem, # front/selected plot
|
||||
]:
|
||||
'''
|
||||
Overlay "group" maxmin sorting.
|
||||
|
||||
Assumes all named flows are in the same co-domain and thus can
|
||||
be sorted as one set.
|
||||
|
||||
Iterates all the named flows and calls the chart api to find
|
||||
their range values and return.
|
||||
|
||||
TODO: really we should probably have a more built-in API for
|
||||
this?
|
||||
|
||||
'''
|
||||
# TODO:
|
||||
# - use this in the ``.ui._fsp`` mutli-maxmin stuff
|
||||
# -
|
||||
|
||||
# force 0 to always be in view
|
||||
group_mx: float = 0
|
||||
group_mn: float = 0
|
||||
mx_up_rng: float = 0
|
||||
mn_down_rng: float = 0
|
||||
pis2ranges: dict[
|
||||
PlotItem,
|
||||
tuple[float, float],
|
||||
] = {}
|
||||
|
||||
for pi in self.overlays:
|
||||
|
||||
# TODO: can we remove this from the widget
|
||||
# and place somewhere more related to UX/Viz?
|
||||
# name = pi.name
|
||||
# chartw = pi.chart_widget
|
||||
viz = pi.viz
|
||||
# viz = chartw._vizs[name]
|
||||
|
||||
out = viz.maxmin()
|
||||
if out is None:
|
||||
return None
|
||||
|
||||
(
|
||||
(x_start, x_stop),
|
||||
read_slc,
|
||||
(ymn, ymx),
|
||||
) = out
|
||||
|
||||
arr = viz.shm.array
|
||||
|
||||
y_start = arr[read_slc.start - 1]
|
||||
y_stop = arr[read_slc.stop - 1]
|
||||
if viz.is_ohlc:
|
||||
y_start = y_start['open']
|
||||
y_stop = y_stop['close']
|
||||
else:
|
||||
y_start = y_start[viz.name]
|
||||
y_stop = y_stop[viz.name]
|
||||
|
||||
# update max for group
|
||||
up_rng = (ymx - y_start) / y_start
|
||||
down_rng = (y_stop - ymn) / y_stop
|
||||
|
||||
# compute directional (up/down) y-range % swing/dispersion
|
||||
mx_up_rng = max(mx_up_rng, up_rng)
|
||||
mn_down_rng = min(mn_down_rng, down_rng)
|
||||
|
||||
pis2ranges[pi] = (ymn, ymx)
|
||||
|
||||
group_mx = max(group_mx, ymx)
|
||||
if force_min is None:
|
||||
group_mn = min(group_mn, ymn)
|
||||
|
||||
return (
|
||||
group_mn if force_min is None else force_min,
|
||||
group_mx,
|
||||
mn_down_rng,
|
||||
mx_up_rng,
|
||||
pis2ranges,
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue