Clean up cross-curve intersect point indexing
When there are `N`-curves we need to consider the smallest x-data-support subset when figuring out for each major-minor pair such that the "shorter" series is always returns aligned to the longer one. This makes the var naming more explicit with `major/minor_i_start` as well as clarifies more stringently a bunch of other variables and explicitly uses the `minor_y_intersect` y value in the scaling transform calcs. Also fixes some debug prints.log_linearized_curve_overlays
parent
052ce65682
commit
0591cb09f6
|
@ -930,17 +930,20 @@ class ChartView(ViewBox):
|
||||||
|
|
||||||
for chart_name, chart in plots.items():
|
for chart_name, chart in plots.items():
|
||||||
|
|
||||||
# Viz "group" maxmins table; presumes that some path
|
# Common `PlotItem` maxmin table; presumes that some path
|
||||||
# graphics (and thus their backing data sets)
|
# graphics (and thus their backing data sets) are in the
|
||||||
# are in the same co-domain and thus can be sorted
|
# same co-domain and view box (since the were added
|
||||||
# as one set per plot.
|
# a separate graphics objects to a common plot) and thus can
|
||||||
mxmns_by_pi: dict[
|
# be sorted as one set per plot.
|
||||||
|
mxmns_by_common_pi: dict[
|
||||||
pg.PlotItem,
|
pg.PlotItem,
|
||||||
tuple[float, float],
|
tuple[float, float],
|
||||||
] = {}
|
] = {}
|
||||||
|
|
||||||
# collect certain flows into groups and do a common calc to
|
# collect certain flows have grapics objects **in seperate
|
||||||
|
# plots/viewboxes** into groups and do a common calc to
|
||||||
# determine auto-ranging input for `._set_yrange()`.
|
# determine auto-ranging input for `._set_yrange()`.
|
||||||
|
# this is primarly used for our so called "log-linearized
|
||||||
mxmn_groups: dict[
|
mxmn_groups: dict[
|
||||||
set[Viz],
|
set[Viz],
|
||||||
set[Viz, tuple[float, float]],
|
set[Viz, tuple[float, float]],
|
||||||
|
@ -967,15 +970,15 @@ class ChartView(ViewBox):
|
||||||
) = out
|
) = out
|
||||||
|
|
||||||
pi = viz.plot
|
pi = viz.plot
|
||||||
mxmn = mxmns_by_pi.get(pi)
|
mxmn = mxmns_by_common_pi.get(pi)
|
||||||
if mxmn:
|
if mxmn:
|
||||||
yrange = mxmns_by_pi[pi] = (
|
yrange = mxmns_by_common_pi[pi] = (
|
||||||
min(yrange[0], mxmn[0]),
|
min(yrange[0], mxmn[0]),
|
||||||
max(yrange[1], mxmn[1]),
|
max(yrange[1], mxmn[1]),
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
mxmns_by_pi[pi] = yrange
|
mxmns_by_common_pi[pi] = yrange
|
||||||
|
|
||||||
if viz.is_ohlc:
|
if viz.is_ohlc:
|
||||||
# print(f'adding {viz.name} to overlay')
|
# print(f'adding {viz.name} to overlay')
|
||||||
|
@ -1019,7 +1022,7 @@ class ChartView(ViewBox):
|
||||||
np.ndarray, # in-view array
|
np.ndarray, # in-view array
|
||||||
],
|
],
|
||||||
] = {}
|
] = {}
|
||||||
max_start: float = 0
|
max_istart: float = 0
|
||||||
major_viz: Viz = None
|
major_viz: Viz = None
|
||||||
|
|
||||||
for viz_name, out in mxmn_groups.items():
|
for viz_name, out in mxmn_groups.items():
|
||||||
|
@ -1029,15 +1032,13 @@ class ChartView(ViewBox):
|
||||||
(ymn, ymx),
|
(ymn, ymx),
|
||||||
) = out
|
) = out
|
||||||
|
|
||||||
x_start = ixrng[0]
|
|
||||||
max_start = max(x_start, max_start)
|
|
||||||
|
|
||||||
# determine start datum in view
|
# determine start datum in view
|
||||||
viz = chart._vizs[viz_name]
|
viz = chart._vizs[viz_name]
|
||||||
arr = viz.shm.array
|
arr = viz.shm.array
|
||||||
in_view = arr[read_slc]
|
in_view = arr[read_slc]
|
||||||
row_start = arr[read_slc.start - 1]
|
row_start = arr[read_slc.start - 1]
|
||||||
# row_stop = arr[read_slc.stop - 1]
|
|
||||||
|
max_istart = max(in_view[0]['index'], max_istart)
|
||||||
|
|
||||||
if viz.is_ohlc:
|
if viz.is_ohlc:
|
||||||
y_med = np.median(in_view['close'])
|
y_med = np.median(in_view['close'])
|
||||||
|
@ -1045,11 +1046,12 @@ class ChartView(ViewBox):
|
||||||
else:
|
else:
|
||||||
y_med = np.median(in_view[viz.name])
|
y_med = np.median(in_view[viz.name])
|
||||||
y_start = row_start[viz.name]
|
y_start = row_start[viz.name]
|
||||||
# y_stop = row_stop[viz.name]
|
|
||||||
|
|
||||||
print(
|
# x_start = ixrng[0]
|
||||||
f'{viz.name} -> (x_start: {x_start}, y_start: {y_start}\n'
|
# print(
|
||||||
)
|
# f'{viz.name} ->\n'
|
||||||
|
# f'(x_start: {x_start}, y_start: {y_start}\n'
|
||||||
|
# )
|
||||||
start_datums[viz.plot.vb] = (
|
start_datums[viz.plot.vb] = (
|
||||||
viz,
|
viz,
|
||||||
y_start,
|
y_start,
|
||||||
|
@ -1080,17 +1082,14 @@ class ChartView(ViewBox):
|
||||||
mn_down_rng = min(mn_down_rng, down_rng)
|
mn_down_rng = min(mn_down_rng, down_rng)
|
||||||
|
|
||||||
print(
|
print(
|
||||||
'####################\n'
|
|
||||||
f'{viz.name}@{chart_name} group mxmn calc\n'
|
f'{viz.name}@{chart_name} group mxmn calc\n'
|
||||||
'--------------------\nn'
|
'--------------------\n'
|
||||||
f'y_start: {y_start}\n'
|
f'y_start: {y_start}\n'
|
||||||
f'ymn: {ymn}\n'
|
f'ymn: {ymn}\n'
|
||||||
f'ymx: {ymx}\n'
|
f'ymx: {ymx}\n'
|
||||||
f'mx_disp: {mx_disp}\n'
|
f'mx_disp: {mx_disp}\n'
|
||||||
'####################\n'
|
|
||||||
f'up %: {up_rng * 100}\n'
|
f'up %: {up_rng * 100}\n'
|
||||||
f'down %: {down_rng * 100}\n'
|
f'down %: {down_rng * 100}\n'
|
||||||
'####################\n'
|
|
||||||
f'mx up %: {mx_up_rng * 100}\n'
|
f'mx up %: {mx_up_rng * 100}\n'
|
||||||
f'mn down %: {mn_down_rng * 100}\n'
|
f'mn down %: {mn_down_rng * 100}\n'
|
||||||
)
|
)
|
||||||
|
@ -1128,28 +1127,39 @@ class ChartView(ViewBox):
|
||||||
# that the intersecting y-value is used as the
|
# that the intersecting y-value is used as the
|
||||||
# reference point for scaling minor curve's
|
# reference point for scaling minor curve's
|
||||||
# y-range based on the major curves y-range.
|
# y-range based on the major curves y-range.
|
||||||
abs_ifirst = minor_in_view[0]['index']
|
|
||||||
mshm = major_viz.shm
|
|
||||||
abs_i_start = max(
|
|
||||||
abs_ifirst,
|
|
||||||
mshm.array['index'][0],
|
|
||||||
)
|
|
||||||
# get intersection point y-values for both curves
|
# get intersection point y-values for both curves
|
||||||
|
# abs_i_start = max_istart
|
||||||
|
|
||||||
|
mshm = major_viz.shm
|
||||||
|
minor_i_start = minor_in_view[0]['index']
|
||||||
|
major_i_start = mshm.array['index'][0],
|
||||||
|
abs_i_start = max(
|
||||||
|
minor_i_start,
|
||||||
|
major_i_start,
|
||||||
|
)
|
||||||
|
|
||||||
y_maj_intersect = mshm._array[abs_i_start][key]
|
y_maj_intersect = mshm._array[abs_i_start][key]
|
||||||
y_min_intersect = minor_in_view[abs_i_start - abs_ifirst]
|
y_minor_intersect = viz.shm._array[abs_i_start][key]
|
||||||
|
|
||||||
# TODO: probably write this as a compile cpython or
|
# TODO: probably write this as a compile cpython or
|
||||||
# numba func.
|
# numba func.
|
||||||
|
|
||||||
|
# if abs_i_start > major_i_start:
|
||||||
|
|
||||||
# compute directional (up/down) y-range
|
# compute directional (up/down) y-range
|
||||||
# % swing/dispersion starting at the reference index
|
# % swing/dispersion starting at the reference index
|
||||||
# determined by the above indexing arithmetic.
|
# determined by the above indexing arithmetic.
|
||||||
y_ref = y_maj_intersect
|
y_ref = y_maj_intersect
|
||||||
assert y_ref
|
if not y_ref:
|
||||||
|
breakpoint()
|
||||||
|
|
||||||
r_up = (major_mx - y_ref) / y_ref
|
r_up = (major_mx - y_ref) / y_ref
|
||||||
r_down = (major_mn - y_ref) / y_ref
|
r_down = (major_mn - y_ref) / y_ref
|
||||||
ymn = y_start * (1 + r_down)
|
|
||||||
ymx = y_start * (1 + r_up)
|
minor_y_start = y_minor_intersect
|
||||||
|
ymn = minor_y_start * (1 + r_down)
|
||||||
|
ymx = minor_y_start * (1 + r_up)
|
||||||
|
|
||||||
# XXX: handle out of view cases where minor curve
|
# XXX: handle out of view cases where minor curve
|
||||||
# now is outside the range of the major curve. in
|
# now is outside the range of the major curve. in
|
||||||
|
@ -1159,42 +1169,47 @@ class ChartView(ViewBox):
|
||||||
# is side (up/down) specific.
|
# is side (up/down) specific.
|
||||||
new_maj_mxmn: None | tuple[float, float] = None
|
new_maj_mxmn: None | tuple[float, float] = None
|
||||||
if y_max > ymx:
|
if y_max > ymx:
|
||||||
y_ref = y_min_intersect[key]
|
y_ref = y_minor_intersect
|
||||||
r_up_minor = (y_max - y_ref) / y_ref
|
r_up_minor = (y_max - y_ref) / y_ref
|
||||||
new_maj_ymx = y_maj_intersect * (1 + r_up_minor)
|
new_maj_ymx = y_maj_intersect * (1 + r_up_minor)
|
||||||
new_maj_mxmn = (major_mn, new_maj_ymx)
|
new_maj_mxmn = (major_mn, new_maj_ymx)
|
||||||
ymx = y_max
|
|
||||||
|
|
||||||
print(
|
print(
|
||||||
f'{view.name} OUT OF RANGE:\n'
|
f'{view.name} OUT OF RANGE:\n'
|
||||||
f'MAJOR is {major_viz.name}\n'
|
'--------------------\n'
|
||||||
f'y_max:{y_max} > ymx:{ymx}\n'
|
f'y_max:{y_max} > ymx:{ymx}\n'
|
||||||
|
f'RESCALE MAJOR {major_viz.name}:\n'
|
||||||
|
f'{new_maj_mxmn}\n'
|
||||||
)
|
)
|
||||||
|
ymx = y_max
|
||||||
|
|
||||||
if y_min < ymn:
|
if y_min < ymn:
|
||||||
y_ref = y_min_intersect[key]
|
y_ref = y_minor_intersect
|
||||||
r_down_minor = (y_min - y_ref) / y_ref
|
r_down_minor = (y_min - y_ref) / y_ref
|
||||||
new_maj_ymn = y_maj_intersect * (1 + r_down_minor)
|
new_maj_ymn = y_maj_intersect * (1 + r_down_minor)
|
||||||
new_maj_mxmn = (
|
new_maj_mxmn = (
|
||||||
new_maj_ymn,
|
new_maj_ymn,
|
||||||
new_maj_ymx[1] if new_maj_mxmn else major_mx
|
new_maj_mxmn[1] if new_maj_mxmn else major_mx
|
||||||
|
)
|
||||||
|
print(
|
||||||
|
f'{view.name} OUT OF RANGE:\n'
|
||||||
|
'--------------------\n'
|
||||||
|
f'y_min:{y_min} < ymn:{ymn}\n'
|
||||||
|
f'RESCALE MAJOR {major_viz.name}:\n'
|
||||||
|
f'{new_maj_mxmn}\n'
|
||||||
)
|
)
|
||||||
ymn = y_min
|
ymn = y_min
|
||||||
|
|
||||||
print(
|
|
||||||
f'{view.name} OUT OF RANGE:\n'
|
|
||||||
f'MAJOR is {major_viz.name}\n'
|
|
||||||
f'y_min:{y_min} < ymn:{ymn}\n'
|
|
||||||
)
|
|
||||||
|
|
||||||
if new_maj_mxmn:
|
if new_maj_mxmn:
|
||||||
|
major_mx, major_mn = new_maj_mxmn
|
||||||
major_viz.plot.vb._set_yrange(
|
major_viz.plot.vb._set_yrange(
|
||||||
yrange=new_maj_mxmn,
|
yrange=new_maj_mxmn,
|
||||||
|
# range_margin=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
print(
|
print(
|
||||||
f'{view.name} APPLY group mxmn\n'
|
f'{view.name} APPLY group mxmn\n'
|
||||||
f'y_start: {y_start}\n'
|
'--------------------\n'
|
||||||
|
f'minor_y_start: {minor_y_start}\n'
|
||||||
f'mn_down_rng: {mn_down_rng * 100}\n'
|
f'mn_down_rng: {mn_down_rng * 100}\n'
|
||||||
f'mx_up_rng: {mx_up_rng * 100}\n'
|
f'mx_up_rng: {mx_up_rng * 100}\n'
|
||||||
f'scaled ymn: {ymn}\n'
|
f'scaled ymn: {ymn}\n'
|
||||||
|
|
Loading…
Reference in New Issue