Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
9ace053
Copy timestamps from source to FSP dest buffer
goodboy Nov 26, 2022
86d09d9
Rename `Flow` -> `Viz`
goodboy Nov 24, 2022
baee86a
Rename `.ui._flows.py` -> `.ui._render.py`
goodboy Nov 24, 2022
e45bc4c
Move `ui._compression`/`._pathops` to `.data` subpkg
goodboy Nov 24, 2022
d3f5ff1
Go back to hard-coded index field
goodboy Nov 25, 2022
5b08e9c
Add breakpoint on -ve range for now
goodboy Nov 28, 2022
6cacd7d
Make `Viz.slice_from_time()` take input array
goodboy Nov 28, 2022
5a0673d
Add `Viz.bars_range()` (moved from chart API)
goodboy Nov 28, 2022
be21f98
Pepper render routines with time-slice calls
goodboy Nov 28, 2022
696c6f8
First attempt, field-index agnostic formatting
goodboy Nov 28, 2022
166d14a
Simplify formatter update methodology
goodboy Nov 29, 2022
9133103
Attempt to make `.default_view()` time-index ready
goodboy Nov 29, 2022
344d2ee
Facepalm: pass correct flume to each FSP chart group..
goodboy Nov 29, 2022
ac1f37a
Expect `index_field: str` in all graphics objects
goodboy Nov 30, 2022
702ae29
Add `Viz.index_field: str`, pass to graphics objs
goodboy Nov 30, 2022
25a75e5
Fix `.default_view()` to view-left-of-data
goodboy Nov 30, 2022
2b9ca5f
Call `Viz.bars_range()` from display loop
goodboy Nov 30, 2022
f3bab82
Comment out bps for time indexing
goodboy Nov 30, 2022
eb9ab20
Don't disable non-enabled vlm chart y-autoranging
goodboy Nov 30, 2022
5affad9
Enable/disable vlm chart yranging (TO SQUASH)
goodboy Nov 30, 2022
3d5695f
Explicitly enable chart widget yranging in display init
goodboy Nov 30, 2022
6ea04f8
Drop diff state tracking in formatter
goodboy Nov 30, 2022
7f3f6f8
Move path ops routines to top of mod
goodboy Nov 30, 2022
382a619
Fix from-time index slicing?
goodboy Nov 30, 2022
309ae24
Look up "index field" in display cycles
goodboy Nov 30, 2022
7ec21c7
Rename `.ui._pathops.py` -> `.ui._formatters.py
goodboy Nov 30, 2022
9052ed5
Move qpath-ops routines back to separate mod
goodboy Nov 30, 2022
7124a13
Move (unused) path gen routines to `.ui._pathops`
goodboy Dec 1, 2022
2e67e98
Go with explicit `.data._m4` mod name
goodboy Dec 1, 2022
031d796
Facepalm: actually return latest index on time slice fail..
goodboy Dec 1, 2022
cca3417
Facepalm: put graphics cycle in `do_ds: bool` block..
goodboy Dec 2, 2022
e4a0d4e
Markup OHLC->path gen with `numba` issue #
goodboy Dec 2, 2022
bf88b40
Facepalm**2: fix array-read-slice, like actually..
goodboy Dec 2, 2022
d5844ce
Delegate formatter `.index_field` to the parent `Viz`
goodboy Dec 3, 2022
a439269
Drop `index_field` input to renders, add `.read()` profiling
goodboy Dec 3, 2022
a33f58a
Move `Flume.slice_from_time()` to `.data._pathops` mod func
goodboy Dec 3, 2022
58b36db
Use step size to determine last datum bar gap
goodboy Dec 3, 2022
a3844f9
Use step size to determine bar gaps
goodboy Dec 3, 2022
6ca8334
Use index (time) step to calc OHLC bar/line uppx threshold
goodboy Dec 3, 2022
46808fb
Rewrite `slice_from_time()` using `numba`
goodboy Dec 3, 2022
12857a2
Adjust all `slice_from_time()` calls to not expect mask
goodboy Dec 3, 2022
0bdb726
Flip over to epoch-time based x-domain indexing
goodboy Dec 4, 2022
bb84715
Make `.default_view()` time step aware
goodboy Dec 5, 2022
f2c0987
Use uniform step arithmetic in `slice_from_time()`
goodboy Dec 6, 2022
2669ced
Drop `_slice_from_time()`
goodboy Dec 6, 2022
d649a7d
Drop old breakpoint
goodboy Dec 6, 2022
98438e2
Drop `Flume.view_data()`
goodboy Dec 6, 2022
e252f70
Add `.x_last()` meth to flow graphics
goodboy Dec 7, 2022
5ab4e54
Add gap detection for `stop_t`, though only report atm
goodboy Dec 7, 2022
5020975
Re-implement `.default_view()` on `Viz`
goodboy Dec 7, 2022
d2aad74
Delegate to `Viz.default_view()` on chart
goodboy Dec 7, 2022
96b871c
Draw last datums on boot
goodboy Dec 7, 2022
44f50e3
Implement `stop_t` gap adjustments; the good lord said it is the problem
goodboy Dec 8, 2022
35a16de
Block out `do_print` stuff inside `Viz.maxmin()`
goodboy Dec 8, 2022
2a797d3
Add back `.default_view()` slice logic for `int` indexing
goodboy Dec 8, 2022
5216a6b
Drop passing `render_data` to `Curve.draw_last_datum()`
goodboy Dec 8, 2022
135627e
Slicec to an extra index around each timestamp input
goodboy Dec 8, 2022
7aef317
Add some commented debug prints for default fmtr
goodboy Dec 8, 2022
9fcc6f9
Restore coord-cache resetting
goodboy Dec 8, 2022
3bed142
Handle time-indexing for fill arrows
goodboy Dec 9, 2022
0663880
Fix formatter xy ndarray first prepend case
goodboy Dec 13, 2022
c5dd67e
Right, do index lookup for int-index as well..
goodboy Dec 13, 2022
3638ae8
Drop unused `read_src_from_key: bool` to `.format_to_1d()`
goodboy Dec 13, 2022
4d74bc2
Fix line -> bars on 6x UPPX
goodboy Dec 14, 2022
3019c35
Move `Viz` layer to new `.ui` mod
goodboy Dec 14, 2022
1410418
Move `DisplayState.incr_info()` -> `Viz`
goodboy Dec 14, 2022
530b273
Add global `i_step` per overlay to `DisplayState`
goodboy Dec 14, 2022
edf721f
Make `LinearRegion` link using epoch-time index
goodboy Dec 15, 2022
9333095
Ugh, use `bool` flag to determine index field..
goodboy Dec 15, 2022
24b384f
Set `path_arrays_from_ohlc(use_time_index=True)` on epoch indexing
goodboy Dec 16, 2022
0d0675a
`Viz._index_field` a `typing.Literal[str]`
goodboy Dec 16, 2022
444768d
Adjust OHLC bar x-offsets to be time span matched
goodboy Dec 16, 2022
51f2461
Add `IncrementalFormatter.x_offset: np.ndarray`
goodboy Dec 16, 2022
50ef4ef
Align step curves the same as OHLC bars
goodboy Dec 16, 2022
3300a24
Use array-`int`-indexing on single feed
goodboy Dec 16, 2022
dea1c1c
Make `Viz.incr_info()` sample rate agnostic
goodboy Dec 17, 2022
1ece704
Add `ChartPlotWidget.main_viz: Viz` convenience `@property`
goodboy Dec 17, 2022
bc17308
Drop coordinate cacheing from `BarItems`, causes weird jitter on pan
goodboy Dec 19, 2022
bf8ea33
Add type annots to vars inside `Render.render()`
goodboy Dec 19, 2022
ed1f64c
Fix gap detection on RHS; always bin-search on overshot time range
goodboy Dec 19, 2022
ffb57f0
Rename `reset` -> `reset_cache`
goodboy Dec 19, 2022
06f1b94
Make `Viz.incr_info()` do treading with time-index, and appending wit…
goodboy Dec 19, 2022
b652149
Make `.increment_view()` take in a `datums: int` and always scale it …
goodboy Dec 19, 2022
efbb8e8
Fix overlayed slow chart "treading"
goodboy Dec 19, 2022
98de22a
Enable the experimental `QPrivatePath` functionality from latest `pyq…
goodboy Dec 19, 2022
f30a48b
Use `np.diff()` on last 16 samples instead of only last datum pair
goodboy Dec 21, 2022
cdec478
Add commented append slice-len sanity check
goodboy Dec 22, 2022
a5eed8f
Fix x-axis labelling when using an epoch domain
goodboy Dec 23, 2022
bfc6014
Fix history array name
goodboy Jan 13, 2023
7ce3f10
Just-offset-from-arrow-marker on slow chart
goodboy Dec 24, 2022
a7d78a3
Use left-style index search on RHS scan as well
goodboy Dec 27, 2022
fc17187
Drop edge case from `slice_from_time()`
goodboy Dec 28, 2022
459cbfd
Further fixes `Viz.default_view()` and `.index_step()`
goodboy Dec 28, 2022
6a0c369
Drop `._index_step` from formatters and instead defer to `Viz.index_s…
goodboy Dec 28, 2022
c1988c4
Add a parent-type for graphics: `FlowGraphic`
goodboy Dec 26, 2022
340045a
Make `FlowGraphic.x_last()` be optionally `None`
goodboy Dec 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
746 changes: 370 additions & 376 deletions piker/ui/_pathops.py → piker/data/_formatters.py

Large diffs are not rendered by default.

137 changes: 18 additions & 119 deletions piker/ui/_compression.py → piker/data/_m4.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,30 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.

'''
Graphics related downsampling routines for compressing to pixel
limits on the display device.
Graphics downsampling using the infamous M4 algorithm.

This is one of ``piker``'s secret weapons allowing us to boss all other
charting platforms B)

(AND DON'T YOU DARE TAKE THIS CODE WITHOUT CREDIT OR WE'LL SUE UR F#&@* ASS).

NOTES: this method is a so called "visualization driven data
aggregation" approach. It gives error-free line chart
downsampling, see
further scientific paper resources:
- http://www.vldb.org/pvldb/vol7/p797-jugel.pdf
- http://www.vldb.org/2014/program/papers/demo/p997-jugel.pdf

Details on implementation of this algo are based in,
https://github.com/pikers/piker/issues/109

'''
import math
from typing import Optional

import numpy as np
from numpy.lib import recfunctions as rfn
from numba import (
jit,
njit,
# float64, optional, int64,
)

Expand All @@ -35,109 +48,6 @@
log = get_logger(__name__)


def hl2mxmn(ohlc: np.ndarray) -> np.ndarray:
'''
Convert a OHLC struct-array containing 'high'/'low' columns
to a "joined" max/min 1-d array.

'''
index = ohlc['index']
hls = ohlc[[
'low',
'high',
]]

mxmn = np.empty(2*hls.size, dtype=np.float64)
x = np.empty(2*hls.size, dtype=np.float64)
trace_hl(hls, mxmn, x, index[0])
x = x + index[0]

return mxmn, x


@jit(
# TODO: the type annots..
# float64[:](float64[:],),
nopython=True,
)
def trace_hl(
hl: 'np.ndarray',
out: np.ndarray,
x: np.ndarray,
start: int,

# the "offset" values in the x-domain which
# place the 2 output points around each ``int``
# master index.
margin: float = 0.43,

) -> None:
'''
"Trace" the outline of the high-low values of an ohlc sequence
as a line such that the maximum deviation (aka disperaion) between
bars if preserved.

This routine is expected to modify input arrays in-place.

'''
last_l = hl['low'][0]
last_h = hl['high'][0]

for i in range(hl.size):
row = hl[i]
l, h = row['low'], row['high']

up_diff = h - last_l
down_diff = last_h - l

if up_diff > down_diff:
out[2*i + 1] = h
out[2*i] = last_l
else:
out[2*i + 1] = l
out[2*i] = last_h

last_l = l
last_h = h

x[2*i] = int(i) - margin
x[2*i + 1] = int(i) + margin

return out


def ohlc_flatten(
ohlc: np.ndarray,
use_mxmn: bool = True,

) -> tuple[np.ndarray, np.ndarray]:
'''
Convert an OHLCV struct-array into a flat ready-for-line-plotting
1-d array that is 4 times the size with x-domain values distributed
evenly (by 0.5 steps) over each index.

'''
index = ohlc['index']

if use_mxmn:
# traces a line optimally over highs to lows
# using numba. NOTE: pretty sure this is faster
# and looks about the same as the below output.
flat, x = hl2mxmn(ohlc)

else:
flat = rfn.structured_to_unstructured(
ohlc[['open', 'high', 'low', 'close']]
).flatten()

x = np.linspace(
start=index[0] - 0.5,
stop=index[-1] + 0.5,
num=len(flat),
)
return x, flat


def ds_m4(
x: np.ndarray,
y: np.ndarray,
Expand All @@ -160,16 +70,6 @@ def ds_m4(
This is more or less an OHLC style sampling of a line-style series.

'''
# NOTE: this method is a so called "visualization driven data
# aggregation" approach. It gives error-free line chart
# downsampling, see
# further scientific paper resources:
# - http://www.vldb.org/pvldb/vol7/p797-jugel.pdf
# - http://www.vldb.org/2014/program/papers/demo/p997-jugel.pdf

# Details on implementation of this algo are based in,
# https://github.com/pikers/piker/issues/109

# XXX: from infinite on downsampling viewable graphics:
# "one thing i remembered about the binning - if you are
# picking a range within your timeseries the start and end bin
Expand Down Expand Up @@ -256,8 +156,7 @@ def ds_m4(
return nb, x_out, y_out, ymn, ymx


@jit(
nopython=True,
@njit(
nogil=True,
)
def _m4(
Expand Down
Loading