Skip to content

Min/max curve downsampling preserving peaks - #85

Merged
PierreRaybaut merged 2 commits into
developfrom
feature/83-minmax-downsampling
Oct 29, 2026
Merged

PierreRaybaut merged 2 commits into
developfrom
feature/83-minmax-downsampling

Conversation

@PierreRaybaut

Copy link
Copy Markdown
Contributor

Closes #83. Part of DataLab-Platform/DataLab#453 (curve readability).

Problem

Curve downsampling kept one point out of N (data[::N]), which discards extrema. Narrow peaks may disappear or change height depending on their position relative to the stride, and the envelope of noisy signals looks thinner than it is.

Changes

Downsampling method

  • New CurveParam.dsamp_method parameter, shown in the curve parameters dialog:
    • min/max (new default): the minimum and the maximum of each group of 2 × N points are kept, in their original order, together with the first and last points. The number of points is about the same as with the stride method.
    • stride: the former method, which keeps one point out of N.
  • NaN values are ignored, except in groups containing only NaN values, which keep one NaN so that the curve is still interrupted there.
  • Files saved before this change (without dsamp_method) load with the default value.

Indices of the points kept

  • minmax_downsampling_indices(data, factor) is vectorized with NumPy.
  • CurveItem.get_dsamp_indices() returns the indices of the points kept. dsamp() uses them, so X, Y and error data are downsampled consistently (ErrorBarCurveItem included).
  • Vertical curves are downsampled according to their X values.

Point handles

  • hit_test maps original indices to indices of points kept, for both methods.
  • move_local_point_to now moves the original point corresponding to the drawn point. It used the handle as an index into the full data, so a different point was moved when downsampling was enabled.
  • EditPointTool edits original points through these indices.
  • The new CurveItem.frozen_downsampling() context keeps the points drawn while a point is dragged. Otherwise, with min/max downsampling, a moved point could be replaced by another point of its group.

Translations

  • French translations of the new parameter.

Tests

  • New plotpy/tests/unit/test_curve_downsampling.py, covering:
    • extrema and endpoints kept for several factors;
    • special cases: short, constant and NaN data;
    • both methods on curves;
    • error bars;
    • frozen downsampling;
    • hit_test and moving points on downsampled curves.
  • test_builder_curve.py checks both methods.
  • Full PlotPy suite (plotpy/tests): 384 passed, 16 skipped locally. test_edit_point_tool, which failed locally on develop, now passes.
  • SigimaX suite (which enables downsampling for large signals) against this branch: 345 passed.

Notes

This PR and #84 (fast thick curves) both modify plotpy/items/curve/base.py, in different methods. The second one to be merged may need a trivial rebase.

Curve downsampling kept one point out of N (`data[::N]`), which discards
extrema: narrow peaks could disappear and the envelope of noisy signals
looked thinner than it is.

- New `CurveParam.dsamp_method` parameter: "minmax" (new default) keeps
  the minimum and the maximum of each group of 2 x N points, in their
  original order, with the first and last points; "stride" restores the
  former method. NaN values are ignored, except in groups containing only
  NaN values, which keep one so that the curve is still interrupted
- The indices of the points kept are stored (`get_dsamp_indices`), so
  that X, Y and error data are downsampled consistently
  (`minmax_downsampling_indices` computes them)
- `hit_test` maps original indices to indices of points kept, and
  `move_local_point_to` moves the corresponding original point (it used
  the handle as an index into the full data)
- `EditPointTool` edits original points through these indices, and keeps
  the points drawn while a point is dragged (`frozen_downsampling`)
- French translations

Closes #83

Assisted-by: Claude Opus 5.5
@PierreRaybaut
PierreRaybaut merged commit eb2a4d6 into develop Oct 29, 2026
4 checks passed
@PierreRaybaut
PierreRaybaut deleted the feature/83-minmax-downsampling branch October 29, 2026 15:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant