v0.20.0
Added
- One Data Inspection tab. The former Raw Data and Data Statistics
tabs are merged into a single Data Inspection tab that, top to bottom,
shows the headline dataset counts, every raw table (Stimuli, Word-level,
Fixation-level, Raw gaze), the per-metric summary statistics, and a new
Column mapping table. - Column mapping table. Data Inspection now lists how each source column was
mapped to the app's canonical fields (per table: Words/IA, Fixations, Raw
gaze) — so you can confirm at a glance which of your columns became the
participant, trial id, word box, fixation duration, and so on. - Share button. A Share popover in the header builds a link that reopens
the app on the current trial with your visualization settings (which layers are
on, the colorscales, animation). The link uses the existing deep-link URL schema
and a new?trial_id=param that lands on the exact trial regardless of how it
was picked; copy it from the popover and send it. Works for the bundled demo,
the synthetic trial, and the OneStop server bundle (an uploaded dataset can't be
rebuilt from a URL, so the link then shares the view settings only, with a note). - Stimuli view. A new Stimuli subtab (first under Data Inspection)
reconstructs each passage from the word table — one row per Text ID with the
full text rebuilt by joining its words in reading order, plus a word count.
It honours the column mapping (groups by the mapped Text ID, uses the mapped
word text) and dedupes shared stimulus words across readers. - Guided setup wizard for uploads. Uploading now walks you through an
incremental flow where only the step you still need to fill stays open
(finished and auto-detected steps tuck away). You name the dataset and set the
display up front, upload each table in its own toggle (each showing its row
count — "✓ N fixations detected — make sure this is the number you expect"),
then map the trial id, participants, texts, and required fields in collapsible
parts. After loading it collapses into a compact Data & mapping panel you
can re-open to tweak. - Reusable named datasets. Finishing an upload saves it (under a name you
choose) as a first-class data source. Switching between it, the bundled demo,
and other datasets is instant — no re-uploading or re-mapping. Add another via
the sidebar's ➕ Add data button. - Optional participant & text. Datasets without a participant column (a
single anonymous reader) or without a text/passage column now load and
visualize — the app fills sensible defaults and hides the Participant / Text
selectors when a dimension has only one value. The wizard maps Participants
and Texts in their own steps (mirroring the Trial id: one shared picker, an
opt-in per-table override, and several columns composable into one id). - Choose the text-highlight column. A new Highlight words by picker chooses
which per-word column (the OneStop answer span by default, or any boolean
column in your data) is marked on the reading text. - Pick the saccade colour. A colour picker under Saccades sets the saccade
line and arrow colour (two-trial comparisons keep their per-scanpath colours). - Saved configs record their export date (and the data source + app version),
shown when you restore one — including a confirmation line under the wizard's
Restore a saved setup box naming where the loaded setup came from. - Keep only the fields you need. The wizard auto-detects reading measures,
linguistic features and condition columns and lets you drop the ones you don't
need; everything unmapped is pruned before processing, which is the main
speed-up on wide datasets (hundreds of columns). - Dynamic trial filters. The Filter trials panel now offers a value
picker for whichever condition fields your dataset actually has (and which you
chose to keep), instead of a fixed set of OneStop-specific conditions. - Display calibration in the loading flow. The Experimental Setup
(monitor size, font, line spacing, background) is now part of the wizard, so
the scanpath is true-to-scale from the first render; it stays adjustable from
the sidebar afterwards. - Step-by-step setup guide. The upload wizard now has a short guided
walkthrough — a ❓ Show setup guide dialog that explains each step (naming,
experimental setup, uploading, column mapping, and finishing). It opens
automatically the first time you set up a dataset in a session and is
replayable anytime. - Export your column mapping. A ⬇️ Download setup button next to Add
dataset saves the current column mapping to a JSON file you can re-apply to
similar data later via Restore a saved setup.
Changed
- Much faster on large datasets. Switching trial, participant, or settings
on a big dataset (hundreds of columns, many trials) is now near-instant
instead of taking minutes — heavy work is cached and thinned, with a visible
loading spinner while the first render builds. - One Visualization controls panel. The former Advanced styling expander
is merged into Visualization controls, grouped by layer (Fixations,
Saccades, Text, Heatmap) with thin separators; per-layer size/colour/colorscale
controls sit under each layer, and the fixation/heatmap colour-range sliders
show whenever they apply (no longer gated behind Show color bars). - Clearer trial-id mapping. One shared Trial ID picker applies to every
table by default (with an opt-in Different trial-id columns per table toggle
that keeps the columns you already picked instead of clearing them), and
defaults to composing the participant and the finest passage id (paragraph,
plus a repeated-reading column when the data has one, so the two readings of a
paragraph stay distinct). If the per-table trial counts disagree the wizard
says so. - Tidier wizard. The mapping steps are grouped under Column mapping with
one collapsible part each (trial id, participants, texts, Column mapping:
Fixations, Column mapping: Text & Interest Areas, More text mappings,
More fixation mappings); a single cross-table Filter trials by picker
and a single Additional fields to keep picker replace the per-table
duplicates; the upload boxes are narrower; and uploaded data defaults to a
2560×1440 monitor. Niche fixation columns (pass index, saccade type/amplitude,
eye) are auto-detected under fields to keep rather than mapped by hand. - Integer colour ranges. The fixation- and heatmap-colour range sliders read
as whole numbers instead of long decimals. - Refreshed the welcome tour to match the current app (the Experimental
Setup / merged Visualization controls panels, the guided upload). - Simpler data-source picker. "Use bundled demo" is now Bundled Demo;
the synthetic trial is no longer offered as a fresh source; a grayed-out
Public Datasets entry previews what's coming. - Clearer Bulk Export controls. The whole-dataset and filtered scopes are
now both All / All filtered trials options inside the Trials to
include picker (no separate checkbox), and the Scope section ends with a live
"N of M trials will be exported" count. Figures are listed one per row
(PDF → SVG → PNG), default to PDF + Config only, the plot-config checkbox
is renamed Config with a short explanation, and the PNG-scale stepper is
compact and only shown when PNG is ticked. - Faster bulk figure export. Rasterizing PNG/SVG/PDF for many trials now
reuses one persistent Kaleido browser for the whole batch instead of
cold-starting Chrome per trial — quicker on large exports and no more
per-trial "Resorting to unclean kill browser." log noise. - Clearer, numbered setup steps. The wizard's sections are now numbered
(1 Dataset name → 5 Filter & keep), the "upload to begin" prompt moved to the
top of the upload step, and a tip points large-dataset users to running the
app locally (pip install scanpath-studio). - See your uploaded tables. Each table's upload box stays open after
uploading and previews its first rows, so you can sanity-check the columns;
the participant and text counts now carry the same "make sure this is the
number you expect to see" reassurance as the trial and row counts.
Fixed
- Animated scanpath replays at its real speed again. The Play button forced a
full figure redraw on every frame, so each frame also paid the ~50 ms cost of
re-rendering the static word boxes + labels; on a long trial that dwarfed the
per-frame budget and the replay crawled — far slower than its quoted time, and
the speed slider stopped helping above ~×4. Every animated trace is now full
length with not-yet-reached fixations masked out, so a frame only changes point
positions and Play can useredraw=False(updating just those traces). The
replay now actually runs atreading time ÷ speed. - Uploading a large EyeLink report no longer crashes the app. Reports with
sentinel values (e.g..in theCURRENT_FIX_PRECISION_MEASURE_*columns)
could read as a column mixing numbers and text, which crashed the cloud worker
when the table was displayed — a full report would die on the cloud while a
small one loaded fine locally. Uploaded CSV/TSV files are now parsed in a
single pass so the column type stays consistent. - Colour bars no longer squash the scanpath. Turning on Show color bars or
colouring fixations by a categorical field used to shrink the plot and throw
off its aspect ratio (the reading text then overflowed its word boxes). The
colour bar / legend now sits in reserved margin, so the plot keeps its true
scale either way. - Dropped the stale Reading regime line from the Text & question panel, and
fixed the per-trial annotations note that pointed at an Annotations sidebar
panel that no longer exists (it lives in 💾 Save & restore). - Word hover shows the real line number. The word tooltip used to always say
Line 1 because it read the sourceline_idxcolumn, which is usually a
constant. It now infers the visual line from the word-box layout (the same
clustering the by-line colouring uses), so each line reads correctly. - Fixation hover no longer shows Pass #NaN. The fixation tooltip dropped the
Pass line, which displayedNaNwhenever the data had no pass/reread column.
Removed
- Noise-flag auto-filtering. A mapped noise/validity column used to silently
drop "noisy" fixations from every view with no way to turn it off. It's gone —
every uploaded fixation is shown. If your data has such a column you can still
keep it (via fields to keep) and filter on it explicitly. - Trimmed the data views. Folding Raw Data and Data Statistics together
dropped the second statistics row (mean fixation duration / saccade amplitude
/ regression rate / reading speed), the fixation-duration distribution plot,
and the per-word measure picker, plus the per-table download buttons,
pagination banner, and descriptive captions — keeping the merged tab focused
on inspecting the tables and their mapping.
Install/upgrade: pip install -U scanpath-studio