visualdynamics.decimate¶
decimate
¶
Peak-keeping decimation: fewer points, with every peak kept.
A record of a million samples is too many to draw point for point, and
keeping every n-th sample can skip the one large peak that was the
reason to look at the record. Peak-keeping decimation 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 is lost.
It is the same method as pyqtgraph's peak downsampling, which the 2-D
plot uses.
The report and the 3-D waterfall both use this module. It works on all of an object's records at once, because the waterfall passes it hundreds of them. It needs only numpy.
This thinning is for drawing, never for a record anything is computed
from: its points sit at uneven times, and an anti-alias filter ahead of
it would take off the peaks it exists to keep. A record taken to a lower
sample rate for analysis goes through core.resample, which filters
first.
Functions:
| Name | Description |
|---|---|
peak_decimate |
|
peak_decimate_rows |
|
shared_peak_indices |
The samples of one shared abscissa to keep, at most |
envelope_rows |
Every record of one object thinned onto the same bins, at most |
Functions:¶
peak_decimate
¶
x and y thinned to at most budget points that keep every
extreme.
The samples are cut into budget // 2 slices, and each slice keeps
its smallest and largest value. y must be real: a caller with
complex data takes the component it wants first, because the
extremes of a complex value are not defined. Input at or under the
budget is returned as given.
NaN marks a gap (a specification is NaN outside its band) and is never kept as an extreme. A slice that is all NaN keeps its first point, so the gap is still drawn as a gap.
Source code in src/visualdynamics/decimate.py
peak_decimate_rows
¶
peak_decimate for every record of one object at once.
rows is a (records, samples) array on the shared abscissa x. The
result is one (x, y) pair per record, and the records no longer share
an abscissa: each keeps its own extremes at their own positions. The
whole block is decimated in one vectorized pass.
Source code in src/visualdynamics/decimate.py
shared_peak_indices
¶
The samples of one shared abscissa to keep, at most budget of
them, so that every row keeps its extremes.
peak_decimate_rows gives each row its own positions, which suits
curves drawn on their own. Rows that share an abscissa on the page,
a measurement and the limits shaded about it, must keep one set of
positions between them, or a band is shaded between points that are
not above each other. This keeps, for every slice of the samples,
the smallest and largest value of every row, with the slices as fine
as the budget allows, and the first and last sample so the extent is
unchanged. The first missing sample of each gap is kept too, while
the gaps fit a quarter of the budget, so a thinned curve breaks
where its data does instead of being drawn across the gap. Rows with
fewer than budget samples keep them all.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rows
|
array_like
|
(rows, samples) values on one abscissa; NaN marks a gap. |
required |
budget
|
int
|
The most samples to keep, at least two for each row and two for the ends. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Sorted sample indices. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the budget cannot hold one slice's extremes for every row. |
Source code in src/visualdynamics/decimate.py
envelope_rows
¶
Every record of one object thinned onto the same bins, at most
bins of them: two points a bin, the bin's least and greatest value
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
abscissas. An envelope on common bins lets a report's time-history
page share one abscissa among its curves, and draws the same
picture, since a bin is far narrower than a pixel at any zoom the
page offers. Input with at most two points a bin is returned as
given.
Returns (axis, envelope): the shared abscissa and a (records,
points) array.