Skip to content

fix(graph): spread the subsample slices over the whole series - #3810

Merged
nicolargo merged 1 commit into
nicolargo:developfrom
Enesuygurs:fix/time-series-subsample
Oct 23, 2026
Merged

nicolargo merged 1 commit into
nicolargo:developfrom
Enesuygurs:fix/time-series-subsample

Conversation

@Enesuygurs

Copy link
Copy Markdown
Contributor

Description

The graph export averages each series down to the chart width with time_series_subsample(points, self.width). The helper cut the data into slices of round(len(data) / sampling) points and took sampling of them. That only covers the whole series when the division is exact:

  • When the rounding goes up, the last slices are empty. t[...][0] raises IndexError (and mean([]) raises StatisticsError in subsample()).
  • When it goes down, the slices stop before the end of the series, so the newest points are left out.

With the defaults ([global] history_size=1200, [graph] width=800), both happen. From 801 to 1199 points, the charts end at the 800th sample. Once the history is full, round(1200 / 800) == 2 and slice 600 is data[1200:1202]. From then on, every export cycle logs:

Export graph failed: list index out of range

and no SVG is written again, for any plugin. The TUI's g key fails the same way.

>>> time_series_subsample([(i, float(i)) for i in range(1200)], 800)
IndexError: list index out of range
>>> time_series_subsample([(i, float(i)) for i in range(1000)], 800)[-1]
(799, 799.0)

The slice bounds are now s * len(data) // sampling. Every slice holds at least one point, and together the slices cover the whole series. time_series_subsample() still keeps the first timestamp and the mean value of each slice, and subsample() gets the same change.

>>> time_series_subsample([(i, float(i)) for i in range(1000)], 800)[-1]
(998, 998.5)

Testing:

  • Added a new test_017_time_series_subsample and two more checks in test_016_subsample (tests/test_core.py). They fail twice on develop; with the fix, all 8 tests in the file pass.
  • A graph export over a full 1200-point history now writes its SVG instead of raising.
  • The graph export tests and ruff pass.

Resume

  • Bug fix: yes
  • New feature: no
  • Fixed tickets: none

time_series_subsample() and subsample() cut the data into slices of
round(len / sampling) points. When the rounding goes up, the last slices
are empty and the call raises IndexError (or StatisticsError); when it
goes down, the newest points are left out. Compute each slice bound as
s * len // sampling instead, so every slice holds at least one point and
the whole series is used.
@nicolargo
nicolargo merged commit 7e14878 into nicolargo:develop Oct 23, 2026
2 of 3 checks passed
@nicolargo

Copy link
Copy Markdown
Owner

Thanks @Enesuygurs

Merged into develop.

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.

2 participants