Heatmap Plotting#

In this tutorial, we will demonstrate how to use the heatmap function from the pymovements.plotting module to create a heatmap of gaze data. The heatmap will show the distribution of gaze positions across the experiment screen, with color values indicating the time spent at each position in seconds.

Preparations#

We import pymovements as the alias pm for convenience.

[1]:
import pymovements as pm

Loading the Dataset#

Let’s start by downloading our ToyDataset and loading in its data:

[2]:
dataset = pm.Dataset('ToyDataset', path='data/ToyDataset')
dataset.download()
dataset.load()
INFO:pymovements.dataset.dataset:
        You are downloading the pymovements Toy Dataset. Please be aware that pymovements does not
        host or distribute any dataset resources and only provides a convenient interface to
        download the public dataset resources that were published by their respective authors.

        Please cite the referenced publication if you intend to use the dataset in your research.

Using already downloaded and verified file: data/ToyDataset/downloads/pymovements-toy-dataset.zip
Extracting pymovements-toy-dataset.zip to data/ToyDataset/raw
100%|██████████| 23/23 [00:00<00:00, 303.43it/s]
[2]:
Dataset
  • DatasetDefinition
    DatasetDefinition
    • None
      None
    • dict (0 items)
      • dict (1 items)
        • dict (4 items)
          • list (5 items)
            • 'timestamp'
            • 'x'
            • (3 more)
          • dict (5 items)
            • Float64
              Float64
            • Float64
              Float64
            • (3 more)
          • (2 more)
      • None
        None
      • Experiment
        Experiment
        • EyeTracker
          EyeTracker
          • None
            None
          • None
            None
          • None
            None
          • None
            None
          • 1000
            1000
          • None
            None
          • None
            None
        • 1000
          1000
        • Screen
          Screen
          • 68
            68
          • 30.2
            30.2
          • 1024
            1024
          • 'upper left'
            'upper left'
          • 38
            38
          • 1280
            1280
          • 15.599386487782953
            15.599386487782953
          • -15.599386487782953
            -15.599386487782953
          • 12.508044410882546
            12.508044410882546
          • -12.508044410882546
            -12.508044410882546
      • None
        None
      • dict (1 items)
        • 'trial_{text_id:d}_{page_id:d}.csv'
          'trial_{text_id:d}_{page_id:d}.csv'
      • dict (1 items)
        • dict (2 items)
          • <class 'int'>
            <class 'int'>
          • <class 'int'>
            <class 'int'>
      • True
        True
      • 'pymovements Toy Dataset'
        'pymovements Toy Dataset'
      • dict (0 items)
        • 'ToyDataset'
          'ToyDataset'
        • list (2 items)
          • 'x'
          • 'y'
        • None
          None
        • list (1 items)
          • ResourceDefinition
            • 'gaze'
              'gaze'
            • 'pymovements-toy-dataset.zip'
              'pymovements-toy-dataset.zip'
            • 'trial_{text_id:d}_{page_id:d}.csv'
              'trial_{text_id:d}_{page_id:d}.csv'
            • dict (2 items)
              • <class 'int'>
                <class 'int'>
              • <class 'int'>
                <class 'int'>
            • '4da622457637a8181d86601fe17f3aa8'
              '4da622457637a8181d86601fe17f3aa8'
            • str
              'http://github.com/aeye-lab/pymovements-toy-dataset/zipball/6cb5d663317bf418cec0c9abe1dde5085a8a8ebd/'
        • 'timestamp'
          'timestamp'
        • 'ms'
          'ms'
        • None
          None
        • None
          None
      • list (0 items)
        • dict (1 items)
          • DataFrame (3 columns, 20 rows)
            shape: (20, 3)
            text_idpage_idfilepath
            i64i64str
            01"aeye-lab-pymovements-toy-datas…
            02"aeye-lab-pymovements-toy-datas…
            03"aeye-lab-pymovements-toy-datas…
            04"aeye-lab-pymovements-toy-datas…
            05"aeye-lab-pymovements-toy-datas…
            31"aeye-lab-pymovements-toy-datas…
            32"aeye-lab-pymovements-toy-datas…
            33"aeye-lab-pymovements-toy-datas…
            34"aeye-lab-pymovements-toy-datas…
            35"aeye-lab-pymovements-toy-datas…
        • list (20 items)
          • Gaze
            • DataFrame (6 columns, 17223 rows)
              shape: (17_223, 6)
              timestimuli_xstimuli_ytext_idpage_idpixel
              i64f64f64i64i64list[f64]
              1988145-1.0-1.001[206.8, 152.4]
              1988146-1.0-1.001[206.9, 152.1]
              1988147-1.0-1.001[207.0, 151.8]
              1988148-1.0-1.001[207.1, 151.7]
              1988149-1.0-1.001[207.0, 151.5]
              2005363-1.0-1.001[361.0, 415.4]
              2005364-1.0-1.001[358.0, 414.5]
              2005365-1.0-1.001[355.8, 413.8]
              2005366-1.0-1.001[353.1, 413.2]
              2005367-1.0-1.001[351.2, 412.9]
            • Events
              Events
              • DataFrame (6 columns, 0 rows)
                shape: (0, 6)
                text_idpage_idnameonsetoffsetduration
                i64i64stri64i64i64
              • list (2 items)
                • 'text_id'
                • 'page_id'
            • list (2 items)
              • 'text_id'
              • 'page_id'
            • Experiment
              Experiment
              • EyeTracker
                EyeTracker
                • None
                  None
                • None
                  None
                • None
                  None
                • None
                  None
                • 1000
                  1000
                • None
                  None
                • None
                  None
              • 1000
                1000
              • Screen
                Screen
                • 68
                  68
                • 30.2
                  30.2
                • 1024
                  1024
                • 'upper left'
                  'upper left'
                • 38
                  38
                • 1280
                  1280
                • 15.599386487782953
                  15.599386487782953
                • -15.599386487782953
                  -15.599386487782953
                • 12.508044410882546
                  12.508044410882546
                • -12.508044410882546
                  -12.508044410882546
          • Gaze
            • DataFrame (6 columns, 29799 rows)
              shape: (29_799, 6)
              timestimuli_xstimuli_ytext_idpage_idpixel
              i64f64f64i64i64list[f64]
              2008305-1.0-1.002[141.4, 153.6]
              2008306-1.0-1.002[141.1, 153.2]
              2008307-1.0-1.002[140.7, 152.8]
              2008308-1.0-1.002[140.6, 152.7]
              2008309-1.0-1.002[140.5, 152.6]
              2038099-1.0-1.002[273.8, 773.8]
              2038100-1.0-1.002[273.8, 774.1]
              2038101-1.0-1.002[273.9, 774.5]
              2038102-1.0-1.002[274.0, 774.4]
              2038103-1.0-1.002[274.0, 773.9]
            • Events
              Events
              • DataFrame (6 columns, 0 rows)
                shape: (0, 6)
                text_idpage_idnameonsetoffsetduration
                i64i64stri64i64i64
              • list (2 items)
                • 'text_id'
                • 'page_id'
            • list (2 items)
              • 'text_id'
              • 'page_id'
            • Experiment
              Experiment
              • EyeTracker
                EyeTracker
                • None
                  None
                • None
                  None
                • None
                  None
                • None
                  None
                • 1000
                  1000
                • None
                  None
                • None
                  None
              • 1000
                1000
              • Screen
                Screen
                • 68
                  68
                • 30.2
                  30.2
                • 1024
                  1024
                • 'upper left'
                  'upper left'
                • 38
                  38
                • 1280
                  1280
                • 15.599386487782953
                  15.599386487782953
                • -15.599386487782953
                  -15.599386487782953
                • 12.508044410882546
                  12.508044410882546
                • -12.508044410882546
                  -12.508044410882546
          • (18 more)
        • PosixPath('data/ToyDataset')
          PosixPath('data/ToyDataset')
        • DatasetPaths
          DatasetPaths
          • PosixPath('data/ToyDataset')
            PosixPath('data/ToyDataset')
          • PosixPath('data/ToyDataset/downloads')
            PosixPath('data/ToyDataset/downloads')
          • PosixPath('data/ToyDataset/events')
            PosixPath('data/ToyDataset/events')
          • PosixPath('data/ToyDataset/precomputed_events')
            PosixPath('data/ToyDataset/precomputed_events')
          • PosixPath
            PosixPath('data/ToyDataset/precomputed_reading_measures')
          • PosixPath('data/ToyDataset/preprocessed')
            PosixPath('data/ToyDataset/preprocessed')
          • PosixPath('data/ToyDataset/raw')
            PosixPath('data/ToyDataset/raw')
          • PosixPath('data/ToyDataset')
            PosixPath('data/ToyDataset')
        • list (0 items)
          • list (0 items)

            After loading the dataset, we will transform the pixel coordinates to degrees.

            [3]:
            
            dataset.pix2deg()
            
            [3]:
            
            Dataset
            • DatasetDefinition
              DatasetDefinition
              • None
                None
              • dict (0 items)
                • dict (1 items)
                  • dict (4 items)
                    • list (5 items)
                      • 'timestamp'
                      • 'x'
                      • (3 more)
                    • dict (5 items)
                      • Float64
                        Float64
                      • Float64
                        Float64
                      • (3 more)
                    • (2 more)
                • None
                  None
                • Experiment
                  Experiment
                  • EyeTracker
                    EyeTracker
                    • None
                      None
                    • None
                      None
                    • None
                      None
                    • None
                      None
                    • 1000
                      1000
                    • None
                      None
                    • None
                      None
                  • 1000
                    1000
                  • Screen
                    Screen
                    • 68
                      68
                    • 30.2
                      30.2
                    • 1024
                      1024
                    • 'upper left'
                      'upper left'
                    • 38
                      38
                    • 1280
                      1280
                    • 15.599386487782953
                      15.599386487782953
                    • -15.599386487782953
                      -15.599386487782953
                    • 12.508044410882546
                      12.508044410882546
                    • -12.508044410882546
                      -12.508044410882546
                • None
                  None
                • dict (1 items)
                  • 'trial_{text_id:d}_{page_id:d}.csv'
                    'trial_{text_id:d}_{page_id:d}.csv'
                • dict (1 items)
                  • dict (2 items)
                    • <class 'int'>
                      <class 'int'>
                    • <class 'int'>
                      <class 'int'>
                • True
                  True
                • 'pymovements Toy Dataset'
                  'pymovements Toy Dataset'
                • dict (0 items)
                  • 'ToyDataset'
                    'ToyDataset'
                  • list (2 items)
                    • 'x'
                    • 'y'
                  • None
                    None
                  • list (1 items)
                    • ResourceDefinition
                      • 'gaze'
                        'gaze'
                      • 'pymovements-toy-dataset.zip'
                        'pymovements-toy-dataset.zip'
                      • 'trial_{text_id:d}_{page_id:d}.csv'
                        'trial_{text_id:d}_{page_id:d}.csv'
                      • dict (2 items)
                        • <class 'int'>
                          <class 'int'>
                        • <class 'int'>
                          <class 'int'>
                      • '4da622457637a8181d86601fe17f3aa8'
                        '4da622457637a8181d86601fe17f3aa8'
                      • str
                        'http://github.com/aeye-lab/pymovements-toy-dataset/zipball/6cb5d663317bf418cec0c9abe1dde5085a8a8ebd/'
                  • 'timestamp'
                    'timestamp'
                  • 'ms'
                    'ms'
                  • None
                    None
                  • None
                    None
                • list (0 items)
                  • dict (1 items)
                    • DataFrame (3 columns, 20 rows)
                      shape: (20, 3)
                      text_idpage_idfilepath
                      i64i64str
                      01"aeye-lab-pymovements-toy-datas…
                      02"aeye-lab-pymovements-toy-datas…
                      03"aeye-lab-pymovements-toy-datas…
                      04"aeye-lab-pymovements-toy-datas…
                      05"aeye-lab-pymovements-toy-datas…
                      31"aeye-lab-pymovements-toy-datas…
                      32"aeye-lab-pymovements-toy-datas…
                      33"aeye-lab-pymovements-toy-datas…
                      34"aeye-lab-pymovements-toy-datas…
                      35"aeye-lab-pymovements-toy-datas…
                  • list (20 items)
                    • Gaze
                      • DataFrame (7 columns, 17223 rows)
                        shape: (17_223, 7)
                        timestimuli_xstimuli_ytext_idpage_idpixelposition
                        i64f64f64i64i64list[f64]list[f64]
                        1988145-1.0-1.001[206.8, 152.4][-10.697598, -8.852399]
                        1988146-1.0-1.001[206.9, 152.1][-10.695183, -8.859678]
                        1988147-1.0-1.001[207.0, 151.8][-10.692768, -8.866956]
                        1988148-1.0-1.001[207.1, 151.7][-10.690352, -8.869381]
                        1988149-1.0-1.001[207.0, 151.5][-10.692768, -8.874233]
                        2005363-1.0-1.001[361.0, 415.4][-6.932438, -2.386672]
                        2005364-1.0-1.001[358.0, 414.5][-7.006376, -2.408998]
                        2005365-1.0-1.001[355.8, 413.8][-7.060582, -2.426362]
                        2005366-1.0-1.001[353.1, 413.2][-7.12709, -2.441245]
                        2005367-1.0-1.001[351.2, 412.9][-7.173881, -2.448686]
                      • Events
                        Events
                        • DataFrame (6 columns, 0 rows)
                          shape: (0, 6)
                          text_idpage_idnameonsetoffsetduration
                          i64i64stri64i64i64
                        • list (2 items)
                          • 'text_id'
                          • 'page_id'
                      • list (2 items)
                        • 'text_id'
                        • 'page_id'
                      • Experiment
                        Experiment
                        • EyeTracker
                          EyeTracker
                          • None
                            None
                          • None
                            None
                          • None
                            None
                          • None
                            None
                          • 1000
                            1000
                          • None
                            None
                          • None
                            None
                        • 1000
                          1000
                        • Screen
                          Screen
                          • 68
                            68
                          • 30.2
                            30.2
                          • 1024
                            1024
                          • 'upper left'
                            'upper left'
                          • 38
                            38
                          • 1280
                            1280
                          • 15.599386487782953
                            15.599386487782953
                          • -15.599386487782953
                            -15.599386487782953
                          • 12.508044410882546
                            12.508044410882546
                          • -12.508044410882546
                            -12.508044410882546
                    • Gaze
                      • DataFrame (7 columns, 29799 rows)
                        shape: (29_799, 7)
                        timestimuli_xstimuli_ytext_idpage_idpixelposition
                        i64f64f64i64i64list[f64]list[f64]
                        2008305-1.0-1.002[141.4, 153.6][-12.268583, -8.823284]
                        2008306-1.0-1.002[141.1, 153.2][-12.275749, -8.832989]
                        2008307-1.0-1.002[140.7, 152.8][-12.285302, -8.842695]
                        2008308-1.0-1.002[140.6, 152.7][-12.28769, -8.845121]
                        2008309-1.0-1.002[140.5, 152.6][-12.290078, -8.847547]
                        2038099-1.0-1.002[273.8, 773.8][-9.071149, 6.490168]
                        2038100-1.0-1.002[273.8, 774.1][-9.071149, 6.497527]
                        2038101-1.0-1.002[273.9, 774.5][-9.06871, 6.50734]
                        2038102-1.0-1.002[274.0, 774.4][-9.066271, 6.504886]
                        2038103-1.0-1.002[274.0, 773.9][-9.066271, 6.492621]
                      • Events
                        Events
                        • DataFrame (6 columns, 0 rows)
                          shape: (0, 6)
                          text_idpage_idnameonsetoffsetduration
                          i64i64stri64i64i64
                        • list (2 items)
                          • 'text_id'
                          • 'page_id'
                      • list (2 items)
                        • 'text_id'
                        • 'page_id'
                      • Experiment
                        Experiment
                        • EyeTracker
                          EyeTracker
                          • None
                            None
                          • None
                            None
                          • None
                            None
                          • None
                            None
                          • 1000
                            1000
                          • None
                            None
                          • None
                            None
                        • 1000
                          1000
                        • Screen
                          Screen
                          • 68
                            68
                          • 30.2
                            30.2
                          • 1024
                            1024
                          • 'upper left'
                            'upper left'
                          • 38
                            38
                          • 1280
                            1280
                          • 15.599386487782953
                            15.599386487782953
                          • -15.599386487782953
                            -15.599386487782953
                          • 12.508044410882546
                            12.508044410882546
                          • -12.508044410882546
                            -12.508044410882546
                    • (18 more)
                  • PosixPath('data/ToyDataset')
                    PosixPath('data/ToyDataset')
                  • DatasetPaths
                    DatasetPaths
                    • PosixPath('data/ToyDataset')
                      PosixPath('data/ToyDataset')
                    • PosixPath('data/ToyDataset/downloads')
                      PosixPath('data/ToyDataset/downloads')
                    • PosixPath('data/ToyDataset/events')
                      PosixPath('data/ToyDataset/events')
                    • PosixPath('data/ToyDataset/precomputed_events')
                      PosixPath('data/ToyDataset/precomputed_events')
                    • PosixPath
                      PosixPath('data/ToyDataset/precomputed_reading_measures')
                    • PosixPath('data/ToyDataset/preprocessed')
                      PosixPath('data/ToyDataset/preprocessed')
                    • PosixPath('data/ToyDataset/raw')
                      PosixPath('data/ToyDataset/raw')
                    • PosixPath('data/ToyDataset')
                      PosixPath('data/ToyDataset')
                  • list (0 items)
                    • list (0 items)

                      We now have a position column available:

                      [4]:
                      
                      dataset.gaze[5]
                      
                      [4]:
                      
                      Gaze
                      • DataFrame (7 columns, 23054 rows)
                        shape: (23_054, 7)
                        timestimuli_xstimuli_ytext_idpage_idpixelposition
                        i64f64f64i64i64list[f64]list[f64]
                        2415266-1.0-1.011[176.8, 140.2][-11.420403, -9.148145]
                        2415267-1.0-1.011[176.7, 139.8][-11.422806, -9.157834]
                        2415268-1.0-1.011[176.7, 139.3][-11.422806, -9.169943]
                        2415269-1.0-1.011[176.6, 139.3][-11.42521, -9.169943]
                        2415270-1.0-1.011[176.7, 139.3][-11.422806, -9.169943]
                        2438315-1.0-1.011[649.9, 633.9][0.260146, 3.038748]
                        2438316-1.0-1.011[650.1, 633.7][0.265149, 3.033792]
                        2438317-1.0-1.011[650.2, 633.5][0.26765, 3.028836]
                        2438318-1.0-1.011[650.0, 633.2][0.262648, 3.021402]
                        2438319-1.0-1.011[649.7, 633.1][0.255144, 3.018924]
                      • Events
                        Events
                        • DataFrame (6 columns, 0 rows)
                          shape: (0, 6)
                          text_idpage_idnameonsetoffsetduration
                          i64i64stri64i64i64
                        • list (2 items)
                          • 'text_id'
                          • 'page_id'
                      • list (2 items)
                        • 'text_id'
                        • 'page_id'
                      • Experiment
                        Experiment
                        • EyeTracker
                          EyeTracker
                          • None
                            None
                          • None
                            None
                          • None
                            None
                          • None
                            None
                          • 1000
                            1000
                          • None
                            None
                          • None
                            None
                        • 1000
                          1000
                        • Screen
                          Screen
                          • 68
                            68
                          • 30.2
                            30.2
                          • 1024
                            1024
                          • 'upper left'
                            'upper left'
                          • 38
                            38
                          • 1280
                            1280
                          • 15.599386487782953
                            15.599386487782953
                          • -15.599386487782953
                            -15.599386487782953
                          • 12.508044410882546
                            12.508044410882546
                          • -12.508044410882546
                            -12.508044410882546

                      Creating a Heatmap#

                      Let’s create a heatmap using the heatmap function from the pymovements library. We will use the default gridsize of 10x10 with interpolation and display the colorbar.

                      [5]:
                      
                      figure = pm.plotting.heatmap(
                          gaze=dataset.gaze[5],
                          position_column='pixel',
                          origin='upper',
                          show_cbar=True,
                          cbar_label='Time [s]',
                          title='Gaze Heatmap with Interpolation On',
                          xlabel='X [pix]',
                          ylabel='Y [pix]',
                          gridsize=[10, 10]
                      )
                      
                      ../_images/tutorials_heatmap_11_0.png

                      To better understand the effect of the gridsize parameter on the heatmap, we can turn off the interpolation. By doing this, we can clearly visualize the individual bins used to calculate the heatmap. With interpolation turned off, the heatmap will display the raw bin values rather than a smoothed representation.

                      [6]:
                      
                      figure = pm.plotting.heatmap(
                          dataset.gaze[5],
                          position_column='pixel',
                          origin='upper',
                          show_cbar=True,
                          cbar_label='Time [s]',
                          title='Gaze Heatmap with Interpolation Off',
                          xlabel='X [pix]',
                          ylabel='Y [pix]',
                          gridsize=[10, 10],
                          interpolation='none'
                      )
                      
                      ../_images/tutorials_heatmap_13_0.png

                      Increasing the gridsize parameter results in a finer grid and more detailed heatmap representation. With a higher grid size, we divide the plot into smaller bins, which can capture more nuances in the data distribution

                      [7]:
                      
                      figure = pm.plotting.heatmap(
                          dataset.gaze[5],
                          position_column='pixel',
                          origin='upper',
                          show_cbar=True,
                          cbar_label='Time [s]',
                          title='Gaze Heatmap with Higher Grid Size',
                          xlabel='X [pix]',
                          ylabel='Y [pix]',
                          gridsize=[25, 25]
                      )
                      
                      ../_images/tutorials_heatmap_15_0.png