visualdynamics.decimate¶
decimate
¶
Peak-keeping decimation: fewer points, every peak kept.
A million-sample record cannot go to a renderer point for point, and
plain striding is the wrong thinning: it walks straight past the one
spike that was the reason to look at the record. The peak-keeping
reading cuts the samples into equal slices and keeps each slice's
smallest and largest value at their own abscissa positions, so no
resonance, dropout or shock thins away — the same reading pyqtgraph's
peak downsampling gives the 2-D plot.
One implementation, used by the report (a document, not a scope) and by the 3-D waterfall (a scene with a point budget). The core is vectorized over whole records at once because the waterfall hands it hundreds of them: as a per-bin Python loop the same work took 10.6 s on a 320-record million-sample history, batched it is 1.3 s — both measured. numpy only.
Functions:
| Name | Description |
|---|---|
peak_decimate |
(x, y) thinned to about |
peak_decimate_rows |
|
envelope_rows |
Every record of one object thinned onto the same |
Functions:¶
peak_decimate
¶
(x, y) thinned to about budget points that keep every extreme.
Real values; a caller reading complex data extracts its component first, because "the extremes" of a complex value is not a question with one answer. Input at or under the budget is returned as given.
NaN marks a gap (a specification is NaN outside its band) and never wins an extreme. A slice that is all gap keeps its first point, so the gap survives to be drawn as a gap.
Source code in src/visualdynamics/decimate.py
peak_decimate_rows
¶
peak_decimate for every record of one object at once.
The records share x going in but not coming out: each keeps its
own extremes at their own positions. One vectorized pass over the
whole (records, samples) block, which is what makes decimating a
320-record million-sample history cost tenths of a second rather
than tens.
Source code in src/visualdynamics/decimate.py
envelope_rows
¶
Every record of one object thinned onto the same bins: two
points a bin, the bin's least and greatest in the order they
occurred, at the bin's first and last sample time.
peak_decimate_rows keeps each record's extremes at their own
positions, so a page carrying two dozen records carries two dozen
time axes. A report's time-history page shares one axis among its
curves (2026-09-20: it is what halved the page), and an envelope
on common bins draws the same picture — the bin is far narrower
than a pixel at any zoom the page offers. Input at or under two
points a bin is returned as given, one axis for all.