Skip to main content

Interactive Streamlit workbench for visualizing eye-tracking-while-reading scanpaths, computing reading measures, and exporting figures and tabular data.

Project description

Scanpath Studio

PyPI Python versions Live demo Docs CI License: MIT

An interactive workbench for visualizing eye-tracking-while-reading data. Drop in a trial and see the scanpath the way the reader saw it — words at their true on-screen positions, with fixations, saccades, a density heatmap, and animated replay layered on top, all exportable as publication-ready figures.

It is dataset-agnostic (auto-detects EyeLink / Gazepoint / snake-case columns) and ships with a small OneStop demo, so you can try it with zero setup.

Authors: Omer Shubi, Keren Gruteke Klein, and others (TBD) — LACC Lab, Technion.

A reading scanpath replayed fixation by fixation

A scanpath replayed fixation by fixation over the text the reader saw.

Try it

Live demo (zero install): https://scanpath-studio.streamlit.app

pip install scanpath-studio
scanpath-studio      # launches the app in your browser

What it does

The scanpath plot is built from layers you toggle independently:

  • Text drawn at the exact pixel coordinates the participant saw.
  • Fixations sized and colored by any column in your data (duration, GPT-2 surprisal, word frequency, …).
  • Saccades, with backward jumps (regressions) standing out.
  • Areas of interest (word boxes from your data) and a word-level heatmap (total fixation duration, count, …).

On top of that:

  • Animated replay — watch the scanpath unfold at real or scaled speed; export as interactive HTML, GIF, or MP4.
  • Compare readings — overlay two trials on one canvas or place them side by side (e.g. ordinary vs. information-seeking, first vs. repeated, L1 vs. L2).
  • Critical-span, out-of-text & by-line highlights — mark an answer span, flag fixations outside every word box, or color fixations by text line.
  • Triage — star, tag, and annotate trials; save and restore everything as a JSON sidecar.
  • Bulk export — one zip of per-trial PNG + SVG figures, plot settings, and tabular data across every filtered trial.

Two readers of the same paragraph, animated on a shared real-time clock

Overlay a second reading to compare two readers of the same text on a shared clock.

The app is organized into three tabs:

Tab What's there
Scanpath Visualization The layered scanpath: a Browse by selection row above the plot (trial / text / participant) and, beside it, a right-hand control rail with Animate and Compare toggles plus the per-layer visualization controls (style each scanpath independently). The trial's key info shows as configurable chips above the plot. Below: three subtabs — Annotations, Stimulus & questions, and Export, where Export bundles single-trial and bulk export (HTML / GIF / MP4 and figures / settings / tabular data across the filtered trials — or the whole dataset).
Corpus Analysis Two subtabs: Generations (WIP) — a real scanpath vs. several model-generated ones over the same text, scored by similarity (placeholders for now); and Aggregated Views — trends of a metric by trial index and within-trial fixation index, per-text heatmaps pooled over readers, and grouped metric distributions.
Data Inspection Paginated word / fixation / raw-gaze tables (CSV + Parquet download), summary statistics, and the active column mapping.

The Scanpath Studio app

Your data

Upload CSV, TSV, Parquet, or Feather tables for words/AoIs, fixations, and (optionally) raw gaze. Columns are auto-detected from common EyeLink, Gazepoint, and snake-case conventions; a sidebar Column mapping panel overrides any guess. The loader bends to fit real corpora — many files per table (concatenated with a source_file tag), a single report (words- or fixations-only), stimulus-level word boxes broadcast across readers, and AoI-sequence fixations placed at word/character-box centers.

If your data carries only raw fixations, the app computes the canonical per-word measures itself — FFD, FPRT (gaze duration), RPD (go-past), TFD (dwell), plus skips and regressions, following Rayner (1998) and Inhoff & Radach (1998). Pre-aggregated EyeLink columns, when present, take precedence.

A ready-made PoTeC loader (Potsdam Textbook Corpus) exercises that flexible pipeline end to end:

import scanpath_studio as sps

words, fixations = sps.load_potec("data/PoTeC", download=True)   # ~45 MB on first call
fig = sps.plot_scanpath(words, fixations, "0", "b0", canvas_size=(1680, 1050))

Command line & Python API

Everything the app draws is also available headless — same pipeline, same figure.

scanpath-studio render --sample --list-trials              # what's available
scanpath-studio render --sample -o scanpath.html           # interactive HTML
scanpath-studio render --words ia.csv --fixations fix.csv -p p1 -t t3 -o figure.png
scanpath-studio render --sample --animate -o replay.html   # animated replay
import scanpath_studio as sps

words, fixations = sps.load_scanpath_data("ia.csv", "fixations.csv")  # paths, globs, or lists; either table optional
sps.list_trials(words, fixations)
fig = sps.plot_scanpath(words, fixations, "p1", "t3")     # every layer toggle is a kwarg
sps.save_figure(fig, "scanpath.png")                       # .html / .png / .svg / .pdf
measures = sps.compute_word_metrics(words, fixations)      # FFD / FPRT / RPD / TFD …

HTML export is browser-free; PNG/SVG/PDF/GIF/MP4 go through Kaleido (run plotly_get_chrome -y once). See scanpath-studio render --help for all flags.

Run from source

git clone https://github.com/lacclab/scanpath-studio.git
cd scanpath-studio
pip install -e ".[test]"          # or: uv sync
streamlit run streamlit_app.py

Tested on Python 3.11–3.14. Run the tests with pytest; see AGENTS.md for an architectural overview.

Documentation

Full docs — getting started, the Python API, the CLI reference, data format, and export/troubleshooting — are at https://lacclab.github.io/scanpath-studio/ (built from docs/ with MkDocs Material). Build them locally with:

pip install -e ".[docs]"
mkdocs serve

Citation

A system-demo paper is in preparation — citation TBD. Until then, cite the software via GitHub's "Cite this repository" button (generated from CITATION.cff).

If you use the bundled demo data, please cite the OneStop corpus:

@article{berzak2025onestop,
  title     = {{OneStop}: A 360-Participant {E}nglish Eye Tracking Dataset
               with Different Reading Regimes},
  author    = {Berzak, Yevgeni and Malmaud, Jonathan and Shubi, Omer
               and Meiri, Yoav and Lion, Ella and Levy, Roger},
  journal   = {Scientific Data},
  year      = {2025},
  publisher = {Nature Publishing Group},
  doi       = {10.1038/s41597-025-06272-2},
  url       = {https://www.nature.com/articles/s41597-025-06272-2},
}

The bundled demo is a subset of OneStop Eye Movements, used under its original license (docs).

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scanpath_studio-0.22.0.tar.gz (842.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scanpath_studio-0.22.0-py3-none-any.whl (787.5 kB view details)

Uploaded Python 3

File details

Details for the file scanpath_studio-0.22.0.tar.gz.

File metadata

  • Download URL: scanpath_studio-0.22.0.tar.gz
  • Upload date:
  • Size: 842.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for scanpath_studio-0.22.0.tar.gz
Algorithm Hash digest
SHA256 a2978b655bba174ad9a087ff095d579f4df4e08ef9f3a68cc3b3b19fc99f0b31
MD5 4e70542c68c72650270d3af21401e55e
BLAKE2b-256 0fdac09a67a994eadf803bba03e7fb597f68d4fabe9677249981816f867ab05a

See more details on using hashes here.

Provenance

The following attestation bundles were made for scanpath_studio-0.22.0.tar.gz:

Publisher: publish.yml on lacclab/scanpath-studio

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file scanpath_studio-0.22.0-py3-none-any.whl.

File metadata

File hashes

Hashes for scanpath_studio-0.22.0-py3-none-any.whl
Algorithm Hash digest
SHA256 eb6bc285f4644d48bf8f31a1867db6086040c88b6c209b1fb13ae0434bc4c043
MD5 d2388610a5609fea4be9fb11ea314362
BLAKE2b-256 ecfd689f7ebc81b8b0957851592b9eeb0ebb485375d66c4ae1e94428e19db5b6

See more details on using hashes here.

Provenance

The following attestation bundles were made for scanpath_studio-0.22.0-py3-none-any.whl:

Publisher: publish.yml on lacclab/scanpath-studio

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page