Why only "left_gaze_x" and "left_gaze_y" to recover eye trajectory (PsychoPy Tobii Workshop)?

I have been using Tobi Fusion Pro eye trackers to record eye movements with PsychoPy and store data as h5py files. I unpacked eye movements data into csv from the recorded h5py file. The unpacked file contains columns such as “left_gaze_x”, “left_gaze_y”, “right_gaze_x”, “right_gaze_y” etc.

I wanted to draw the trajectory of eye movements using those recorded data, but not sure which columns to use. left eye x, y or right eye x y, or combined both via a function.
I plotted the left x y, and right x y, they give similar trajectory but are not completely overlapped.

Below is the partial code that draws the eye trajectory that I found from PsychoPy eye tracking Workshop. It uses the left eye x, y (see code defines x, y). I’m wondering why only left eye info is used? Thank you in advance if anyone could give a hint! :grinning:

here is the link to the eye tracking workshop, shared - Google Drive

see analysis – run_third_datavis.py

filename = gui.fileOpenDlg(prompt = 'Select a trial csv file to plot')[0]

# fetch the participant ID
this_filename = filename.split('/')[-1]
id = this_filename.split("_")[0]
imname = gui.fileOpenDlg(prompt = 'Select the image associated with this trial')[0]
# fetch the participant ID
this_filename = imname.split('/')[-1]
imid = this_filename.split("_")[0]

# What image to overlay on
img = plt.imread(imname)
im_height, im_width = 1, 1.6 # from the psychopy file
xmin = (im_width/2)*-1
xmax = im_width/2
ymin = (im_height/2)*-1
ymax = im_height/2

# Read as pandas dataframe
data = pd.read_csv(filename)

# Convert pandas arrays to no arrays
x = data['left_gaze_x'].to_numpy()
y = data['left_gaze_y'].to_numpy()

if plot_type == 'heatmap':
    # plot x and y values as a heat map
    # Remove nan values
    x = x[~np.isnan(x)]
    y = y[~np.isnan(y)]
    # get the heatmap
    heatmap, xedges, yedges = np.histogram2d(x, y, bins=50, range = [[xmin, xmax], [ymin, ymax]])
    # get the extent
    extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
    # clear figure 
    fig, ax = plt.subplots()
    # plot the heatmap
    ax.imshow(heatmap.T, extent=extent, origin='lower', alpha = 0.5)
    # plot the image
    ax.imshow(img, extent=[xmin, xmax, ymin, ymax], zorder=1, alpha = 0.5)
elif plot_type == 'path':
    fig, ax = plt.subplots()
    # add the image to the plot
    ax.imshow(img, extent=[xmin, xmax, ymin, ymax])
    # plot xy data
    ax.plot(x, y, color = 'yellow')

# show the plot
plt.ylabel('y coordinate (height units)')
plt.xlabel('x coordinate (height units)')
plt.savefig('figures/' + id +'_'+ imid+'.png')

My question is better described as "What metric (left_eye or right_eye X Y) is used to calculate and record data such as '“ROI.num_looks”, “ROI.timesOn”, “ROI.timesOff” in PsychoPy output.

I dug into the source code and found out they used the average of left and right eyes X and Y, see the comments in source code below


    Device.__init__(self, *args, **kwargs['dconfig'])

    # hold last received ioHub eye sample (in ordered array format) from
    # tracker.
    self._latest_sample = EyeTrackerConstants.FUNCTIONALITY_NOT_SUPPORTED

    # holds the last gaze position read from the eye tracker as an x,y tuple. If binocular recording is
    # being performed, this is an average of the left and right gaze
    # position x,y fields.


Left eye X Y Z and right eye X Y Z can be unpacked from the binocular recording (stored in h5py files). To recover the ROI measures from those readings that match with PsychoPy output, the average of left eye and right eye coordinates should be used.