Visualize and compare very dense saccade patterns from long free-viewing eye-tracking data.
HeatMatch turns hundreds or thousands of saccades into continuous orientation fields: at every location it estimates saccade density, mean orientation, and how consistently the saccades agree in orientation. From these fields it draws orientation-coded heatmaps that show where gaze moves and in which direction. It also computes a similarity score for comparing saccade patterns across participants, stimuli, or conditions, without AOIs, scanpath alignment, or manual segmentation.
It was developed for 60-second viewing of paintings (empirical aesthetics, art history) and works for any static stimulus. Python implementation accompanying the paper:
Xingyu Long, Jozsef Arato, Sophia Kury, Anna Miscena, and Raphael Rosenberg. 2026. |
|
- OOI-coded heatmaps — orientation fields visualized with researcher-defined color anchors and confidence-weighted opacity.
- HeatMatch similarity — comparison based on saccade density and orientation.
Per-participant (columns 1–5) and aggregated (column 6) heatmaps for three paintings. Hue = mean saccade orientation relative to OOI; opacity = local confidence. Stimulus images: public domain via Wikimedia Commons — see paper for details.
See the paper for methodology.
- Long, dense viewing. Scanpath comparison methods such as MultiMatch or ScanMatch align scanpaths sequence by sequence. With hundreds of saccades per trial and strongly diverging paths, they become slow and hard to interpret. HeatMatch aggregates instead of aligning, so it scales to arbitrarily dense data.
- Orientation matters. Fixation heatmaps and density-based metrics ignore saccade direction. HeatMatch keeps orientation, so you can ask whether gaze follows horizontal, vertical, diagonal, or symmetric structure in an image, e.g. composition lines in a painting.
- Group, stimulus, and individual comparisons. In the paper, the similarity score recovers the abstract vs. still-life distinction and differences in within-painting agreement. It also reveals stable individual "saccadic signatures" that hold across paintings.
It is not a replacement for sequence-based methods. HeatMatch is permutation-invariant (it ignores saccade order) and treats orientations as unsigned (left-to-right = right-to-left). Use it alongside MultiMatch, ScanMatch, or RQA when order or direction matters.
pip install heatmatchDependencies: numpy, matplotlib, Pillow. For development, clone the repository and run pip install -e ..
import matplotlib.pyplot as plt
from heatmatch import make_reference_grid, make_orientation_field, Heatmap, compute_similarity
W, H = 2880, 2160
onset = ... # (J, 2) saccade start coordinates
offset = ... # (J, 2) saccade end coordinates
pts, xx, yy = make_reference_grid(W, H, grid_resolution=200)
field = make_orientation_field(pts, onset, offset, sigma=50.0, grid_shape=yy.shape)
fig, ax = plt.subplots()
Heatmap(field, W, H).draw(ax, ooi=0.0) # ooi=0 → horizontal, ooi=90 → vertical
plt.show()
# Compare two patterns (fields built on the same grid, e.g. two participants)
result = compute_similarity(field_a, field_b)
s = (result.s_loc + result.s_dir) / 2 # composite HeatMatch score S in [0, 1]
print(result.s_loc, result.s_dir, s)A full worked example is in demo.ipynb. The dataset is not included — download data_anonymized.csv from osf.io/f2xhj and place it in tests/.
make_reference_grid(w, h, grid_resolution) |
Returns (pts, xx, yy); int → square grid, (ny, nx) tuple → rectangular |
make_orientation_field(pts, onset, offset, sigma, grid_shape, ...) |
Returns OrientationField with omega_mean, R, rho |
Heatmap(field, w, h, image=None) |
Caches colormap, opacity, and (optionally) grayscale background image |
Heatmap.draw(ax, ooi, opacity_density_weight, base_opacity, cmap, ...) |
Renders onto ax |
OOI in degrees: 0 = east, 90 = north, 180 = west, 270 = south. Unsigned, so ooi and ooi ± 180 are equivalent.
compute_similarity(field_a, field_b, density_coherence_tradeoff) |
Returns SimilarityResult(s_loc, s_dir) |
| Parameter | Default | Notes |
|---|---|---|
sigma |
50.0 |
Gaussian bandwidth in px. Paper evaluates {50, 100, 150}. |
grid_resolution |
200 |
Int or (ny, nx). Paper uses 200. |
ooi |
0.0 |
Orientation of Interest in degrees. |
opacity_density_weight |
1.0 |
Density vs. coherence for opacity. Recommended 0.5–1.0. |
base_opacity |
0.85 |
Global opacity ceiling; useful with a background image. |
density_coherence_tradeoff |
0.5 |
Density vs. coherence for S_dir. At 1.0, angular information is discarded. |
@article{long2026heatmatch,
author = {Long, Xingyu and Arato, Jozsef and Kury, Sophia and Miscena, Anna and Rosenberg, Raphael},
title = {HeatMatch: Orientation-Aware Visualization and Comparison of Very Dense Saccade Patterns},
journal = {Proc. ACM Comput. Graph. Interact. Tech.},
year = {2026},
volume = {9},
number = {2},
articleno = {18},
doi = {10.1145/3803539},
}