{ "cells": [ { "cell_type": "markdown", "id": "0", "metadata": {}, "source": [ "# Scanpathplot Tutorial: Visualizing Eye Movement Events\n", "\n", "This tutorial demonstrates how to create scanpath plots for eye movement data using pymovements, with a focus on fixation detection." ] }, { "cell_type": "markdown", "id": "1", "metadata": {}, "source": [ "## Step 1: Import Libraries and Load Dataset\n", "\n", "First, we need to import the necessary libraries and load our eye movement dataset. We'll use the {py:class}`~pymovements.datasets.ToyDataset` for this tutorial." ] }, { "cell_type": "code", "execution_count": null, "id": "2", "metadata": {}, "outputs": [], "source": [ "import pymovements as pm\n", "\n", "# Load the ToyDataset\n", "dataset = pm.Dataset('ToyDataset', path='data/ToyDataset')\n", "dataset.download()\n", "dataset.load()" ] }, { "cell_type": "markdown", "id": "3", "metadata": {}, "source": [ "## Step 2: Convert Data Units\n", "\n", "Convert pixel coordinates to degrees of visual angle for more meaningful analysis. This step is important for proper fixation detection as dispersion thresholds are typically defined in degrees." ] }, { "cell_type": "code", "execution_count": null, "id": "4", "metadata": {}, "outputs": [], "source": [ "# Convert pixel coordinates to degrees of visual angle\n", "dataset.pix2deg()\n", "\n", "# Note: We could also compute velocity here if needed:\n", "# dataset.pos2vel('smooth')" ] }, { "cell_type": "markdown", "id": "5", "metadata": {}, "source": [ "## Step 3: Detect Fixations with Different Parameters\n", "\n", "We'll detect fixations using the {py:func}`I-DT (Dispersion-Threshold) algorithm ` with different dispersion threshold values to create two different sets of fixation events that will be plotted separately.\n", "\n", "**Key Parameters:**\n", "- `dispersion_threshold`: Maximum dispersion allowed for fixation points (in degrees)\n", "- `name`: Custom name for the detected events" ] }, { "cell_type": "code", "execution_count": null, "id": "6", "metadata": {}, "outputs": [], "source": [ "# Detect fixations with standard threshold (2.7 degrees)\n", "dataset.detect_events('idt', dispersion_threshold=2.7, name='fixation_2.7_idt')\n", "\n", "# Detect fixations with stricter threshold (1.0 degrees)\n", "dataset.detect_events('idt', dispersion_threshold=1.0, name='fixation_1.0_idt')" ] }, { "cell_type": "markdown", "id": "7", "metadata": {}, "source": [ "## Step 4: Compute Event Properties\n", "\n", "Calculate fixation property `location` that will be used for visualization purposes. This property is added as a separate column named `location` in the events DataFrame, containing the coordinates of the centroid of each fixation. \n", "\n", "**Parameters:**\n", "- `position_column`: Specifies which coordinate system to use for the property. The default value is in degrees, however, in order to generate fixation events containing centroids presented in pixels, its valu has to be explicitely provided. " ] }, { "cell_type": "code", "execution_count": null, "id": "8", "metadata": {}, "outputs": [], "source": [ "# Get the first gaze recording\n", "gaze = dataset.gaze[0]\n", "\n", "# Compute fixation locations using pixel coordinates\n", "gaze.compute_event_properties((\"location\", {'position_column': 'pixel'}))" ] }, { "cell_type": "markdown", "id": "9", "metadata": {}, "source": [ "## Step 5: Default Scanpath Visualization\n", "\n", "Create a basic scanpath plot to visualize the eye movement fixations. Each fixation is presented as a circle with radius proportional to the fixation duration. The method plots fixations with default name `fixation.idt` if the argument `event_name` is not provided. " ] }, { "cell_type": "code", "execution_count": null, "id": "10", "metadata": {}, "outputs": [], "source": [ "# Create a basic scanpath plot\n", "pm.plotting.scanpathplot(gaze)" ] }, { "cell_type": "markdown", "id": "11", "metadata": {}, "source": [ "## Step 6: Advanced Scanpath with Trace Plot\n", "\n", "Create an enhanced visualization that combines scanpath with trace plot. This shows both the fixation sequence with name `fixation1_0.idt` that we created in step 3 and the raw gaze trajectory.\n", "\n", "**Key Parameters:**\n", "- `event_name`: Specifies which fixation events to plot\n", "- `add_traceplot`: Adds the continuous gaze trace to the plot" ] }, { "cell_type": "code", "execution_count": null, "id": "12", "metadata": {}, "outputs": [], "source": [ "# Create enhanced scanpath plot with trace\n", "pm.plotting.scanpathplot(gaze, event_name='fixation1_0.idt', add_traceplot=True)" ] }, { "cell_type": "markdown", "id": "13", "metadata": {}, "source": [ "## What you have learned in this tutorial:\n", "* **Data Loading**: Importing and preparing eye movement data \n", "* **Fixation Detection**: Creating different sets of fixations with different dispersion thresholds\n", "* **Property Computation**: Calculating fixation locations and properties\n", "* **Visualization**: Creating scanpath plots with various parameters\n", "\n" ] } ], "metadata": {}, "nbformat": 4, "nbformat_minor": 5 }