Skip to contents

A single similarity number can hide important differences between scanpaths. Two people might fixate the same locations but in a completely different order, or follow the same trajectory but at different speeds. MultiMatch (Dewhurst et al., 2012) addresses this by evaluating scanpath similarity across five distinct dimensions:

Dimension What it captures
vector Overall shape similarity of saccade vectors
direction Angular similarity of saccade directions
length Similarity of saccade amplitudes
position Spatial proximity of corresponding fixations
duration Similarity of fixation durations

The eyesim implementation adds a sixth metric, position_emd, based on the earth mover’s distance between fixation locations. This captures distributional similarity that is not order-dependent.

How do you compare two scanpaths?

Start by creating two fixation_group objects, convert them to scanpath objects, and call multi_match():

set.seed(1)

simulate_linear <- function(n) {
  fixation_group(
    x = cumsum(rnorm(n, mean = 50, sd = 10)),
    y = cumsum(rnorm(n, mean = 50, sd = 10)),
    duration = rpois(n, lambda = 200),
    onset = 1:n
  )
}

fg1 <- simulate_linear(10)
fg2 <- simulate_linear(12)
Two scanpaths generated from similar linear processes.

Two scanpaths generated from similar linear processes.

sp1 <- scanpath(fg1)
sp2 <- scanpath(fg2)
multi_match(sp1, sp2, screensize = c(500, 500))
#>       mm_vector    mm_direction       mm_length     mm_position     mm_duration 
#>       0.9944381       0.9824906       0.9924735       0.8774572       0.9194313 
#> mm_position_emd 
#>       0.8946239

All metrics are high, consistent with the known similarity of the two scanpaths.

What happens when scanpaths differ structurally?

Let’s compare a linear scanpath against a zigzag pattern:

fg_zigzag <- fixation_group(
  x = cumsum(rep(50, 10)),
  y = cumsum(c(50, -50, 50, -50, 50, -50, 50, -50, 50, -50)),
  duration = rpois(10, lambda = 200),
  onset = 1:10
)

sp_linear <- scanpath(simulate_linear(10))
sp_zigzag <- scanpath(fg_zigzag)
multi_match(sp_linear, sp_zigzag, screensize = c(500, 500))
#>       mm_vector    mm_direction       mm_length     mm_position     mm_duration 
#>       0.9914539       0.9671332       0.9912823       0.6570499       0.9350000 
#> mm_position_emd 
#>       0.6558473

Notice how the direction metric drops substantially — the zigzag and linear paths follow very different angular trajectories.

What do the metrics look like for random scanpaths?

To build intuition about each metric’s range and distribution, let’s simulate 500 pairs of random scanpaths and plot the results:

Distribution of each MultiMatch metric across 500 random scanpath pairs, on a common 0 to 1 scale. Vertical lines mark the medians.

Distribution of each MultiMatch metric across 500 random scanpath pairs, on a common 0 to 1 scale. Vertical lines mark the medians.

None of the metrics sits near zero for unrelated scanpaths. Median similarity for random pairs ranges from 0.57 (Duration) to 0.84 (Length), so a single similarity value has to be read against this baseline, not against zero.

What do extreme matches look like?

Examining the highest- and lowest-scoring pairs for each metric gives concrete insight into what each dimension captures:

The highest- and lowest-scoring random pairs for each MultiMatch metric (rows). Each pair is shown as its two scanpaths side by side; colour is fixation order and point area is duration. Row labels give the high and low scores.

The highest- and lowest-scoring random pairs for each MultiMatch metric (rows). Each pair is shown as its two scanpaths side by side; colour is fixation order and point area is duration. Row labels give the high and low scores.

The highest-scoring pairs are not visibly similar scanpaths: with ten random fixations each, a pair can score highly on one dimension (for example, similar saccade lengths) while differing everywhere else. This is why the five dimensions are reported separately rather than averaged.

How do transformations affect the metrics?

Understanding how each metric responds to spatial and temporal transformations helps you choose the right one for your research question.

Identity (perfect match)

set.seed(7)
fg <- fixation_group(runif(10) * 500, runif(10) * 500,
                     round(runif(10) * 10) + 1, 1:10)
multi_match(scanpath(fg), scanpath(fg), c(500, 500))
#>       mm_vector    mm_direction       mm_length     mm_position     mm_duration 
#>               1               1               1               1               1 
#> mm_position_emd 
#>               1

All metrics are 1.0 — a scanpath is perfectly similar to itself.

Scaling

Scaling the coordinates by 0.5 preserves direction (relative angles are unchanged) but reduces position (absolute locations differ):

fg_scaled <- fg
fg_scaled$x <- fg_scaled$x * 0.5
fg_scaled$y <- fg_scaled$y * 0.5
Original (left) vs. scaled (right) scanpath.

Original (left) vs. scaled (right) scanpath.

multi_match(scanpath(fg), scanpath(fg_scaled), c(500, 500))
#>       mm_vector    mm_direction       mm_length     mm_position     mm_duration 
#>       0.8831983       1.0000000       0.7663966       0.7237247       1.0000000 
#> mm_position_emd 
#>       0.7605673

As expected, direction stays at 1.0, but position drops.

Shuffling fixation order

Keeping the same fixation locations but scrambling their order preserves position (and the EMD) while disrupting direction:

set.seed(3)
fg_shuffled <- fg
ord <- sample(nrow(fg_shuffled))
fg_shuffled$x <- fg_shuffled$x[ord]
fg_shuffled$y <- fg_shuffled$y[ord]
fg_shuffled$duration <- fg_shuffled$duration[ord]
Original (left) vs. order-shuffled (right) scanpath. Same locations, different sequence.

Original (left) vs. order-shuffled (right) scanpath. Same locations, different sequence.

multi_match(scanpath(fg), scanpath(fg_shuffled), c(500, 500))
#>       mm_vector    mm_direction       mm_length     mm_position     mm_duration 
#>       0.8565614       0.7687388       0.7836460       0.7816592       0.6363636 
#> mm_position_emd 
#>       1.0000000

The position_emd remains high (same spatial distribution), while direction drops (the trajectory has changed).

References

Dewhurst, R., Nyström, M., Jarodzka, H., Foulsham, T., Johansson, R., & Holmqvist, K. (2012). It depends on how you look at it: Scanpath comparison in multiple dimensions with MultiMatch, a vector-based approach. Behavior Research Methods, 44, 1079–1100.