Plotting#

Every data object has a plot namespace with the plotting functions (PlotNamespace), e.g. d.plot.plot_pupil(); dir(d.plot) lists them. Pupil plots need pupil data and gaze plots need gaze data; they raise an error if the data are missing. Gaze plots draw the screen as it is seen: pixel y increases downward. All plots use matplotlib, so they can be adjusted and saved as usual. Most functions take eyes=, variables=, plot_range= and units= arguments. units= is the unit of the time axis and of plain numbers in plot_range (and interv of the *_segments plots): plot_range=(0, 20), units="sec" plots the first 20 seconds. Values with units are converted, e.g., plot_range=(0, 20) * u.sec. In all plots that have it, plot_range is the first argument, so it can be given without its name: d.plot.plot_pupil((0, 20) * u.sec).

The examples on this page use the short example dataset with detected blinks:

import pypillometry as pp
from pypillometry import u
import matplotlib.pyplot as plt

d = pp.get_example_data("rlmw_002_short")
d.pupil.blinks_detect()

Each function’s API documentation has another example.

Figures and axes#

All plotting functions follow one of three conventions, depending on how many panels and figures they draw:

  • One panel (e.g., plot_pupil(), plot_masked(), plot_scanpath(), Events.plot(), Intervals.plot(), the plots of the segments and of ROIs): the plot is drawn on ax= (default: the current axes), and the axes are returned. Several plots can be combined in one figure this way:

    fig, axs = plt.subplots(2, 1, figsize=(10, 6))
    d.plot.plot_pupil(plot_range=(0, 20) * u.sec, ax=axs[0])
    d.plot.plot_pupil(plot_range=(20, 40) * u.sec, ax=axs[1])
    
  • Several panels in one figure (plot_timeseries(), plot_heatmap(), plot_calibration(), …): the function makes a new figure of size figsize= and returns it. axes= (one axes per panel) draws on existing axes instead, e.g., fig.axes of an earlier call to overlay two datasets.

  • Several figures (plot_blinks(), plot_intervals() and the *_segments plots): a list of figures of size figsize= is returned; with pdf_file=, they are also written to a multi-page PDF file (and closed).

All of them take title=, and the one-panel plots pass further arguments to matplotlib (e.g., color="red"; see the API documentation of each function). In a notebook, end a line with a plotting function with ; (or assign the result) to hide the returned object.

Time series#

EyeData.plot.plot_pupil

Make a plot of the pupil data using matplotlib.

EyeData.plot.plot_timeseries

Plot a part of the EyeData.

EyeData.plot.plot_masked

Plot masked intervals for specified eyes and variables.

plot_pupil() shows the pupil size of all eyes in one plot, with blinks (red) and events (grey lines):

fig, ax = plt.subplots(figsize=(10, 3))
d.plot.plot_pupil(plot_range=(0, 20) * u.sec, ax=ax)
../_images/plotting-21.png

plot_timeseries() plots each variable (here: gaze and pupil) in its own panel:

fig = d.plot.plot_timeseries(plot_range=(0, 20) * u.sec, units="sec",
                             figsize=(10, 6))
../_images/plotting-31.png

To save a plot, use matplotlib as usual, e.g. fig.savefig("pupil.pdf").

Long recordings#

Plotting a whole recording at once hides the details. These functions split it into many small plots (one figure each), optionally written to a multi-page PDF file with pdf_file=. For interactive browsing, the viewer is usually faster.

EyeData.plot.plot_timeseries_segments

Plot the whole dataset chunked up into segments (usually to a PDF file).

EyeData.plot.plot_pupil_segments

Plot the whole dataset chunked up into segments (usually to a PDF file).

Gaze#

EyeData.plot.plot_heatmap

Plot EyeData as a heatmap.

EyeData.plot.plot_scanpath

Plot EyeData as a scanpath.

EyeData.plot.plot_calibration

Plot spatial calibration data for one or more eyes in subplots.

fig = d.plot.plot_heatmap(eyes="left")

fig, ax = plt.subplots(figsize=(6, 5))
d.plot.plot_scanpath(plot_range=(10, 12) * u.sec, eyes="left", ax=ax)
../_images/plotting-9_00.png
../_images/plotting-9_01.png

plot_calibration() shows the calibration and validation results of the eye tracker (see Spatial calibration). Regions of interest can be drawn on top of heatmaps and scan paths (see Experimental setup and regions of interest).

Comparing versions of the data#

To compare, e.g., raw and filtered data, plot both into the same axes (ax= for one-panel plots, axes=fig.axes for plot_timeseries()) and give each a label_prefix and a style:

filtered = d | pp.pupil.lowpass_filter(cutoff=4)

fig, ax = plt.subplots(figsize=(10, 3))
d.plot.plot_pupil(eyes="left", plot_range=(5, 15) * u.sec, ax=ax,
                  label_prefix="raw", style={"color": "grey"})
filtered.plot.plot_pupil(eyes="left", plot_range=(5, 15) * u.sec, ax=ax,
                         label_prefix="filtered")
../_images/plotting-101.png

See the tutorial Plotting pupillometric data for exploration for more examples.