v0.19.0
Added
- Dark mode. Ships a polished dark theme for the app chrome (☰ →
Settings → Appearance, or follows your OS). The scanpath plot stays light
in both themes, so it always reproduces the experiment's stimulus faithfully. - Raw-gaze-only datasets. Upload just a raw-gaze table (no words or
fixations) and visualize the gaze trace — the Scanpath Visualization tab draws
the time-coloured gaze scatter, the trial picker and Data Statistics work off
the raw gaze, and the fixation-only views (animation, Generations) show a
"needs a fixations table" note. - Upload a config to restore it. The sidebar 💾 Save & restore panel gains a
JSON uploader that re-applies a previously downloaded config — layers, coloring,
sizing, text/highlighting, canvas, axes, trial selection, and annotations —
silently skipping anything that doesn't fit the loaded data.
Changed
- Reorganized layout & usability pass. The Animated Scanpath tab folds
into the main tab (now Scanpath Visualization) as an Animate checkbox;
bulk export moves to its own Bulk Export tab (with an export the whole
dataset option); Multiple Comparison is renamed Generations (WIP).
In the side panel: a Trial Info header (showing the compared trial's info
too), the trial selectors below it, annotations above a collapsible metadata
table, and an Export toggle. Participant-mode selection now offers trial
index / text / trial id. Defaults flip to Fixation index off, saccade
arrows on; "Color fixations by line" is now alineoption in Color
fixations by; Text-highlighting and Heatmap-style options grey out when their
layer is off. The animation's playback speed, info box, and play / pause /
restart + scrub controls all move into one place (speed + info under the
Animate toggle, transport below the plot); default playback is now ×4. The
monitor/font controls (renamed Experimental Setup) move under 📂 Data. - Plot configuration + Annotations merged into 💾 Save & restore. One sidebar
panel saves the full figure configuration, all annotations, and the data
source + column mapping + app version to a single JSON file (and restores the
settings + annotations) — capturing more state than before (text sizing,
highlighting, background).
Fixed
- Animated scanpath text is now true-to-scale. Its transport controls used
to shrink the equal-aspect plot, leaving the word labels oversized relative to
the boxes; the figure now reserves the control space without shrinking the
plot, so the animation matches the static view exactly. - The tutorial is now a guided spotlight tour. The welcome opens centered
like a modal over a closed sidebar — appearing as soon as the page opens,
not after the first full render; the following steps open the sidebar and
drop to a corner card that scrolls the relevant panel into view and pulses
an outline around it. The previous all-dialog style remains one constant
away (tour.TOUR_STYLE = "dialog"). - README trimmed and refreshed — a concise rewrite (264 → 157 lines)
reflecting the current five-tab app, with a regenerated hero GIF and
screenshot. - Simpler, more general column mapping. The Words/IA word-box mapping is now
a single coordinate-format selector (edges ↔ origin+size) plus four fields
instead of eight, and column auto-detection matches names case- and
separator-insensitively (IA_LEFT,ia_leftandParticipant IDall
resolve). Required-field markers now match what the loader actually needs. - Search-engine discoverability. Keyword-rich page title and tagline, so the
<title>and the social/search description Streamlit Cloud serves to crawlers
are no longer brand-only. - Mapping panels grouped under each upload box. On the Upload source each
table's column-mapping panel now sits directly beneath its own upload box
(Words/IA, Fixations, Raw gaze), raw-gaze mapping is a first-class peer, and
every field has a?tooltip describing what it is and how it's used.
Fixed
- Animated scanpath order numbers no longer glide in from the top-left corner —
they now snap on at their fixation. The labels render in a constant-length
text trace, so a new number turns on in place instead of a fresh node
flashing at the (0,0) origin before placement. - The tutorial's Skip/Done buttons now close the dialog instantly instead of
leaving it on screen for the ~10 s full-app rerun.
CI
- Leaner AppTest suite. Data-independent integration tests now boot the tiny
synthetic trial instead of the bundled demo (~10x cheaper per boot, in a
single run), cutting the AppTest file ~4x. The bundled-demo render still gets
guardrail coverage. - Parallel test runs.
pytest -n auto(viapytest-xdist) fans the suite
across the runner's cores, roughly cutting the AppTest-dominated wall-clock to
a third. - Faster dependency install. The test job installs with
uv(cached)
instead ofpip, trimming the install step that now dominates each run. - Test on Python 3.14 (the version Streamlit Cloud runs); CI now runs on pull
requests only. Added a supported-Python-versions badge to the README. - Added a pull request template (
.github/pull_request_template.md) with a
summary/verification prompt and a checklist mirroring the CONTRIBUTING and CI
checks (tests, ruff,[Unreleased]changelog, dependency manifests). - The publish workflow now creates a GitHub release (with the matching CHANGELOG
section as the body) on everyv*tag, alongside the PyPI publish and Slack
post;scripts/changelog_notes.pygained a--format markdownmode for it.
Install/upgrade: pip install -U scanpath-studio