Skip to content

Render trace plots by sample density - #410

Merged
pauladkisson merged 3 commits into
mainfrom
downsample_plots
Aug 3, 2026
Merged

Render trace plots by sample density#410
pauladkisson merged 3 commits into
mainfrom
downsample_plots

Conversation

@pauladkisson

@pauladkisson pauladkisson commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Follow up to #401

Details (AI-generated)

Step 3's preprocessing view sent every sample of every trace to the browser. On a one-hour TDT session (3,704,960 samples per trace) that was 296 MB over the websocket and ~155 s of frozen tab before anything painted, which read as a blank plot. The same page now paints in ~130 ms.

Trace plots are now rendered by per-pixel sample density (datashade) instead of point-by-point lines. The full arrays stay server-side and re-aggregate on zoom and pan, so no sample is dropped and a one-sample artifact spike stays visible at any zoom level. Density rather than a reduced line matters here: with millions of samples in a few hundred pixel columns, a line through each column's minimum and maximum gives the noise band and a real transient identical weight, which is the distinction these plots exist to show.

Affects the artifact-marking and artifact-review plots, the z-score/dF-F review, and the transients peak view.

Relates to #402 and #403.

🤖 Generated with Claude Code

pauladkisson and others added 3 commits July 31, 2026 16:19
Full-length recordings hold millions of samples per trace, which Bokeh shipped
to the browser in full and rendered point by point. On a one-hour TDT session
(3,704,960 samples) the Step-3 preprocessing view pushed 296 MB over the
websocket and took ~155 s to paint, during which the tab was frozen and the
plots showed as empty boxes. Every site switch or table edit repeated the cost.

Wrap the trace curves in downsample1d so the full arrays stay server-side and
only the samples the plot is wide enough to show are sent, re-derived on every
zoom or pan. The m4 algorithm keeps the minimum, maximum, first and last sample
of each pixel column, so the drawn line matches plotting every sample and a
one-sample artifact spike stays visible at any zoom level -- which matters here
because these plots exist to find artifacts. The peak markers in the transients
view are left at full resolution.

The same session now paints in 258 ms and transfers 0.2 MB, with an identical
y-axis range.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The plot builders now return shaded images rather than curves, so assertions
that read sample values off a curve read the image's extent instead. Replace
the m4-line tests with test_shading.py, which covers the property the change
turns on: a one-sample spike is drawn in exactly one pixel column while the
baseline fills every column, so a transient stays visible without being given
the same weight as the noise band.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@pauladkisson
pauladkisson merged commit 350afce into main Aug 3, 2026
12 checks passed
@pauladkisson
pauladkisson deleted the downsample_plots branch August 3, 2026 14:24
pauladkisson added a commit that referenced this pull request Aug 6, 2026
The tonic pages predated PRs #410/#413/#414 and were the last ones still using
the patterns those replaced.

Define Tonic Epochs now mirrors Select Artifact Windows: one form row per window
(label, numeric bounds nudgeable with the arrow keys, delete button) instead of
a fixed three-row Tabulator, an "Add epoch" button, a column header, and an
empty-state hint. Both pages' plots stack z-score and dF/F on a shared, linked
time axis, stretch to the tab width, and render by per-pixel sample density, so
a full-length recording no longer ships every sample to the browser. Editing a
bound repaints the shaded spans through a pipe rather than re-aggregating the
traces. The signal toggle is gone, since both traces are now shown at once.

Windows saved on disk are reloaded when the page reopens, so a revisit shows the
current definitions rather than a blank table.

build_control_signal_fit's panel builder is extracted as _shaded_panel and
shared with the new build_stacked_traces.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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