Initial Setup

Import the library we suggest to use and the package alpscarf.

library(tidyverse)
#import::from(cowplot, plot_grid)
import::from(magrittr, "%<>%")
library(alpscarf)
library(RColorBrewer)

merge_sequence <- function(lsa_df_) {

  lsa_reduced_dwell_df <- NULL

  for (a_p_name in unique(lsa_df_$p_name)){
    df_p <-
      lsa_df_ %>%
      filter(p_name == a_p_name) %>%
      mutate(cum_duration = cumsum(duration))

    runlength <- rle(df_p$AOI)

    rl_table <- tibble(AOI = runlength$values, length = runlength$lengths)
    rl_table %<>%
      mutate(total_duration_current_index = cumsum(length),
             total_duration_pre_index = lag(total_duration_current_index, default = 0),
             dwell_duration = df_p$cum_duration[total_duration_current_index] - c(0, df_p$cum_duration[total_duration_pre_index]),
             p_name = a_p_name
      ) %>%
      select(p_name, AOI, dwell_duration)

    lsa_reduced_dwell_df %<>% bind_rows(rl_table)
  }
  # return
  lsa_reduced_dwell_df
}

Data Import

Import example data. The synthetic dataset example_eye_movement_data.RData includes AOI visit sequences for 3 participants (P1 - P3). The dataset aoi_sequence.RData contains the expected visit order of each AOI, as well as the color association of AOIs.

# specify dataset name & path
dataset_path = "../data"
example_dataset <- file.path(dataset_path, "example_eye_movement_data.RData")
expected_aoi_sequence <- file.path(dataset_path, "aoi_sequence.RData")

# load data  
load(example_dataset)
load(expected_aoi_sequence)

# put AOIs in sorted order
aoi_names_pages_seq %<>%
  arrange(AOI_order)

The AOI visit sequences contains at least 3 columns: "p_name" "AOI" "dwell_duration"

head(eye_movement_data_systhetic)

The expected visit order contains at least two columns: "AOI" and "AOI_order".

head(aoi_names_pages_seq)

In above example dataset, we merge the expected visit order with and color association, resulting the an extra column color.

Generate Alpscarf

When the data is ready, users can generate Alpscarf in following steps:

1. Define colors for AOIs

The association between AOIs and colors MUST be an 1-to-1 mapping; i.e., n AOIs require n colors. An exmaple of such mapping is included in the dataset aoi_sequence.RData.

# define colors
my_palette <- 
  aoi_names_pages_seq$color[]

2. Translate visit sequence into bar height/width

Two funcitons are involved in this step:

# generate Alpscarf dataset
eye_movement_data_systhetic_alp_df <- 
  eye_movement_data_systhetic %>%

  # merge the fixations within the same AOI and derive the dwell duration
  rename(duration = dwell_duration) %>%
  merge_sequence() %>%

  alpscarf_add_height(., aoi_names_pages_seq, 
                      height_mode = "exponential", scale_factor = 0.2) %>%
  alpscarf_add_width()

# for video prototype
#eye_movement_data_systhetic_alp_df$re_reading_bar_length = 0

Note that some parameters are specifiable in the function alpscarf_height_trans. Users can choose from linear mode (height_mode = "linear") and exponential mode (height_mode = "exponential"), which controls the contrast of mountain height (i.e., make high mountains even higher, and vice versa). In exponential mode, users can also specify the base (base_factor) and the scale (scale_factor) of exponent.

3. Generate Alpscarf plot

Now the dataset is ready for generating Alpscarf. In this example, we generate one Alpscarf per participant.

Example 1: Alpscarf in normalized view

# initialise the list storing Alpscarfs, one plot per participant
lsa_scarf_vis <- list()
# specify plot height
plot_height <- max(eye_movement_data_systhetic_alp_df$seq_bar_length)

for(a_p_name in unique(eye_movement_data_systhetic_alp_df$p_name)){
  df_p <-
    eye_movement_data_systhetic_alp_df %>%
    filter(p_name == a_p_name) 

  # for indexing
  a_p_nr <- 
    strsplit(a_p_name,"P")[[1]][2] %>%
    as.numeric()

  # specify the color association of AOIs
  aoi_name_in_order <- 
    aoi_names_pages_seq$AOI[]
  df_p$AOI <- factor(df_p$AOI, levels = aoi_name_in_order)

  # Alpscarf plot generation
  lsa_scarf_vis[[a_p_nr]] <- alpscarf_plot(df_p, my_palette, focus_mode = "transition", plot_type = "alpscarf", ymax = plot_height, NORMALIZED_VIEW = TRUE, title = a_p_name)
}

# plot Alpscarf for all participants
plot(lsa_scarf_vis[[1]])
plot(lsa_scarf_vis[[2]])
plot(lsa_scarf_vis[[3]])

Notice that, ymax specify the height of each plot. To make all Alpscarf comparable, generating Alpscarfs in the same height is highly recommended.

In Example 1, the generate plots are:

Example 2: Alpscarf in unnormalized view

# initialise the list storing Alpscarfs, one plot per participant
lsa_scarf_vis <- list()
# specify plot height
plot_height <- max(eye_movement_data_systhetic_alp_df$seq_bar_length)
# specify plot width range; used in unnormalized view
max_nr_transitions <- 
  eye_movement_data_systhetic_alp_df$trial %>%
  max()
max_sum_dwell_duration <-
  eye_movement_data_systhetic_alp_df %>% 
  group_by(p_name) %>% 
  summarise(total = sum(dwell_duration)) %>% 
  select(total) %>% 
  max()

for(a_p_name in unique(eye_movement_data_systhetic_alp_df$p_name)){
  df_p <-
    eye_movement_data_systhetic_alp_df %>%
    filter(p_name == a_p_name) 

  # for indexing
  a_p_nr <- 
    strsplit(a_p_name,"P")[[1]][2] %>%
    as.numeric()

  # specify the color association of AOIs
  aoi_name_in_order <- 
    aoi_names_pages_seq$AOI[]
  df_p$AOI <- factor(df_p$AOI, levels = aoi_name_in_order)

  # Alpscarf plot generation
  # Alpscarf plot generation
    lsa_scarf_vis[[a_p_nr]] <- alpscarf_plot(df_p, my_palette, focus_mode = "transition", plot_type = "alpscarf", ymax = plot_height, NORMALIZED_VIEW = FALSE, max_nr_transitions = max_nr_transitions, max_sum_dwell_duration = max_sum_dwell_duration, title = a_p_name)
}

# plot Alpscarf for all participants
plot(lsa_scarf_vis[[1]])
plot(lsa_scarf_vis[[2]])
plot(lsa_scarf_vis[[3]])

In addition to setting NORMALIZED_VIEW = FALSE, unnormalized view requires two extra arguments: max_nr_transitions and max_sum_dwell_duration, which define the maximun length of plots in transition-focus mode and duraiton-focus mode respectivelty.

4. (bonus) Distance measures of AOI visit sequences

This part is NOT necessary to generate Alpscarf plot

Additionally, users can get a few descriptive stats (e.g., order_following, rereading ratio), and edit distance between each AOI sequence and the expected visit order.

# generate stats of Alpscarf; NOT required in generating Alpscarf.
stat_table_df <- alpscarf_stats(eye_movement_data_systhetic_alp_df, aoi_names_pages_seq)

head(stat_table_df)


Chia-KaiYang/alpscarf documentation built on May 21, 2020, 4:25 a.m.