Skip to main content

creapy

creapy (pronounced /ˈkɹiə.paɪ/) is eye-tracking visual analytics for art history and empirical aesthetics, developed at the CReA Lab (Lab for Cognitive Research in Art History, Department of Art History, University of Vienna).

Two layers for two audiences (the division announced at DHd 2026: maximal ease of use in the app, analytical depth and flexibility in the library):

  • creapy: a pip-installable, Qt-free Python library for researchers who know some Python: load fixation/saccade tables, build per-stimulus datasets, draw heatmaps, scanpaths and orientation-aware saccade heatmaps (via HeatMatch), AOI metrics and sequences, descriptives, coefficient K, time series and spectra, recurrence quantification, HeatMatch / MultiMatch / ScanMatch similarity with permutation tests. Every plot takes a matplotlib ax, every table is a DataFrame. Documented in docs/LIBRARY.md and tutorial.ipynb.
  • creapy.io: a desktop app (Qt / PySide6) for art historians and other researchers who do not program: import a table, click through the views, filter by participant or time window, export figures and tables. Everything the app shows is a library call; the app adds only windows, sliders, projects and the session log.

Status: prototype in active development, in use at the CReA Lab; the API may still change before 1.0. Source: https://github.com/xysLong/creapy (MIT). Presented as a poster at DHd 2026 (doi:10.5281/zenodo.18703017).

Installation

Non-programmers: do not install Python. Download the double-click app (creapy.io-<version>-macOS.zip, -macOS-intel.zip or -Windows.zip) and follow docs/INSTALL_APP.md: two minutes, one security dialog on first start. Building those bundles: packaging/README.md.

Developers: Python 3.10 or newer. In a terminal (macOS: Terminal; Windows: PowerShell):

python -m venv creapy-env
# macOS / Linux:
source creapy-env/bin/activate
# Windows:
creapy-env\Scripts\activate

pip install "creapy[gui]"    # library + desktop app
pip install creapy           # library only, no Qt

# from a checkout of the repository instead:
pip install -e ".[gui]"

Start the app:

creapy-io            # or: python -m creapy.io

The first screen offers an example dataset (synthetic, twelve invented viewers on two generated pictures) so every view can be tried before any real data is at hand.

Conda users: conda create -n creapy python=3.11 && conda activate creapy && pip install -e ".[gui]".

Data formats

Source What to export Notes
EyeLink DataViewer Fixation report or Saccade report, CSV/Excel, one row per event needs a column with the stimulus image name; TRIAL_INDEX and CURRENT_FIX_PUPIL are picked up; . missing values are handled
Tobii Pro Lab (screen or glasses) Event-based metrics export (TSV, one row per fixation; the file the lab shares) or the Data export (TSV, one row per gaze sample; files above 1.5 GB are read in chunks) each snapshot / medium becomes one stimulus; pupil and viewing distance are carried along. The AOI-based metrics export opens as a table window with charts per AOI
Anything else one row per fixation: participant, stimulus, start time, duration, x, y CSV with , ; or tab, decimal commas fine; map the columns in the import dialog

Coordinates are pixels of the image you provide: use the images at the resolution shown (or the Pro Lab snapshot files). Times may be in s, ms or µs; durations in ms or s; the units are detected.

The views

Fixation heatmap compared by group

Fixation Heatmap (optional shared colour scale) · Fixation Scanpath (numbered, per participant) · Saccade Scanpath · Saccade Heatmap (HeatMatch, orientation of interest) · Saccade Directions (rose diagram) · Areas of Interest (draw rectangles / polygons; dwell time, fixations, visits, time to first fixation; scarf plot; transition matrix; first-fixation order; save/load as JSON) · Time Series (fixation duration, saccade amplitude, coefficient K, pupil size, viewing distance, share of fixations in AOIs; per group; periodogram and scalogram) · Saccade Similarity (HeatMatch: matrix, group boxplot with permutation test, viewer map, similarity over time) · Scanpath Comparison (MultiMatch, ScanMatch, cross-recurrence; same displays) · Recurrence (recurrence plot, RQA table, boxplot by group) · Statistics (per-participant table, group comparison, AOI metrics, boxplots; export CSV/Excel).

scarf plot MultiMatch matrix with groups periodogram

The Show bar above the canvas restricts every view to a participant, a group or a time window (e.g. the first 3 s). Groups are assigned under Analysis, optionally prefilled from a column of the table. Compare Side by Side draws the current view once per group, stimulus or time window; Export This View for All Stimuli writes it once per stimulus into a folder. Projects remember table, images, mapping, groups and AOIs; Undo covers AOI edits and group assignments. Long computations run in a worker thread with a Cancel button. Help → The Analyses Explained describes every measure in plain words; docs/QUICKSTART.pdf is the two-page hand-out. (Screenshots are offscreen renders of the synthetic example dataset.)

Session log (opt-in). Logging > Record session log writes the views, parameter values and filters you use into a text file on your own computer (JSON lines). Nothing is sent anywhere. It exists for usability evaluations; it is off by default.

Library quickstart

Full guide with a view-by-view map of app features to library calls and the API reference: docs/LIBRARY.md. help(creapy.FixationData) (or fix.make_heatmap? in Jupyter) shows the same texts.

import creapy

df, mapping = creapy.load_fixations("fixation_report.csv")          # EyeLink, Tobii Data export or any table
datasets = creapy.datasets_by_stimulus(df, mapping, "stimuli/")     # {stimulus -> (FixationData, SaccadeData)}
fix, sac = next(iter(datasets.values()))
grouping = {p: "expert" if p.startswith("E") else "novice" for p in fix.subjects}

import matplotlib.pyplot as plt
fig, ax = plt.subplots()
fix.make_heatmap(ax, bw_method=0.1, cmap="coolwarm")                 # duration-weighted KDE, participants equal
fix.subset(t_range=(0, 3)).visualize_scanpath(ax, subjects=[fix.subjects[0]])

fix.set_top_down_aoi("face", creapy.AOI.rectangle("face", 600, 100, 800, 300).geom)
print(fix.aoi_metrics())                                             # participant x AOI (dwell, visits, latency)
creapy.show_scarf_plot(ax, fix); creapy.transition_matrix(fix)       # AOI sequences
df_stats = creapy.participant_table(fix, sac)                       # descriptives + coefficient K
creapy.group_comparison(df_stats, grouping)                          # Welch t / Mann-Whitney / ANOVA per measure
creapy.show_group_boxplot(df_stats, "coefficient_K", grouping)       # the Statistics view's boxplot
creapy.show_measure_curve(fix, sac, "fixation_duration", sigma=2)   # the Time Series view's curve
result = sac.compute_heatmatch_similarity(sigma=50)                  # pairwise HeatMatch scores
result.matshow(grouping=grouping); result.permutation_test(grouping)
mm = fix.compute_scanpath_similarity("multimatch")                   # MultiMatch / ScanMatch / cross-recurrence
mm.show_boxplot(grouping); mm.score_overview(grouping)
creapy.participant_rqa(fix)                                          # recurrence quantification
creapy.participant_periodogram(fix)                                  # Lomb-Scargle rhythm per participant

tutorial.ipynb walks through all of this on the example dataset; demo_similarity.ipynb covers the similarity workflow in depth.

Development

pip install -e ".[dev]"
pytest                      # formats, conversions, datasets, offscreen GUI

Layout: creapy/formats/ (table reading, format detection, Tobii loaders), creapy/gaze/ (datasets, conversions), creapy/aoi/ (AOI geometry, sequences), creapy/stats/ (descriptives, time series, recurrence, spectrum), creapy/similarity/ (HeatMatch results, MultiMatch/ScanMatch), creapy/misc/ (contours, utils), creapy/io/ (the Qt app: main.py window, views.py prepare/draw functions, worker.py, project.py, widgets/, style/), creapy/examples/ (synthetic example data), tests/, docs/, packaging/.

Saccade orientation fields and similarity are computed by the heatmatch package and are not reimplemented here. docs/LIBRARY.md is generated from the docstrings by python docs/make_library_reference.py; a test fails when a public library function lacks a docstring or when the GUI gains logic the library does not have.

Citation

Long, X. & Rosenberg, R. (2026). Perspektiven für ein anfängerfreundliches Tool zur Eye-Tracking-Datenvisualisierung in der kognitiven Kunstgeschichte. Book of Abstracts – DHd 2026, 606–607. https://doi.org/10.5281/zenodo.18703017

Long, X., Arató, J., Kury, S., Miscenà, A. & Rosenberg, R. (2026). HeatMatch: Orientation-Aware Visualization and Comparison of Very Dense Saccade Patterns. Proc. ACM Comput. Graph. Interact. Tech. 9(2), Art. 18. https://doi.org/10.1145/3803539

License

MIT (see LICENSE). Contact: Xingyu Long, xingyu.long@univie.ac.at.

Metadata

Release files for creapy 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for creapy 0.1.0
File Size Uploaded Provenance Actions
creapy-0.1.0.tar.gz 420.0 kB Without provenance Details for creapy-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for creapy 0.1.0
File Interpreter ABI Platform Actions
creapy-0.1.0-py3-none-any.whl Python 3 none any Details for creapy-0.1.0-py3-none-any.whl

Total release size: 852.2 kB

Release files / creapy-0.1.0.tar.gz

Download URL creapy-0.1.0.tar.gz
Size 420.0 kB
Tags Source
SHA-256 checksum
How to use checksums
caca7ce71ff778900ce4f128e9ab786892987d62ed5ff72db132e9c1f8b0e677
BLAKE2b-256 checksum
How to use checksums
89a9a24f75ec289b6a53645c8491d3deca4f77a2568d693920cc176310af2f62
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.19

Release files / creapy-0.1.0-py3-none-any.whl

Download URL creapy-0.1.0-py3-none-any.whl
Size 432.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ccefbf0a2502540a875c54ec2c407e8bfa145d3477cde17f9f2336bca362aada
BLAKE2b-256 checksum
How to use checksums
b0c0c782ee476785eaca9405a23e8f9d0cfc924c2a5e4c5b9aaa336e7d9a02b0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.10.19

Security for creapy 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page