Axes length value error when plotting epoched bio data

Hi all,

I am currently working on running some based time-series analyses on some pupil data. I’m currently running into an issue where the plot_image() function in conjunction with the 'bio' data channel.

I am running MNE version 1.3.0, Python 3.10.8, on a Windows 10 system.

Specifically, the code I’m working with is the following:

n_channels = ['eye_x','eye_y','Pupil Area']

sampling_freq = 500 # in Hertz

info = mne.create_info(n_channels, sfreq=sampling_freq, ch_types='bio')

evnt, evntd = mne.events_from_annotations(raws[0])

epochs = mne.Epochs(raws[0], evnt, event_id=evntd, 
                    preload=True, tmin= -0.5, tmax = 0.5,
                    baseline=(-0.3, 0), picks=['Pupil Area']
                    )

epochs.plot_image(picks=['Pupil Area'])

raws[0] is a concatenated raw object (I concatenated multiple individual blocks for one participant to create a time-course over the entire experiment) using the info object I instantiated above. The issue is that i get the following error message **ValueError**: axes must be an array-like of length 0, but the length is 1 from _validate_if_list_of_axes() when attempting to plot the epoched data (calling either conditions or generally).

However, if I change this to another data channel (only tried with MEG or EEG) I do not get this error and the epoched data are plotted but for obvious reasons, the units are not appropriate. I would much rather the 'bio' arbitrary units, at least in lieu of being able to manually adjust these myself.

I was wondering if someone had some insight as to what is going on. For completeness a sample of the epochs data, events data, and event dictionary are posted here:

epochs:

array([[[ -96.67549669,  -96.67549669,  -96.67549669, ...,
          209.32450331,  209.32450331,  210.32450331]],

(there is more data there i just posted the first snippet)

events

array([[    308,       0,      12],
       [   1903,       0,      11],
       [   3366,       0,      10],
       ...,
       [1022141,       0,       2],
       [1023016,       0,       8],
       [1023753,       0,      11]])

event dictionary

{'119': 1,
 '129': 2,
 '139': 3,
 '149': 4,
 '219': 5,
 '229': 6,
 '239': 7,
 '249': 8,
 '319': 9,
 '329': 10,
 '339': 11,
 '349': 12}

Any help would be much appreciated and if there is anything more I could provide to help please let me know.

Cheers, Andrew

As a quick update, ive managed to ‘work around’ this by setting the channel types to EEG and when calling epochs.plot_image() manually setting units = 'a.u.' and scalings = 1 .

As I am quite new to this package, I would like to reword my original question now. does .plot_image() support bio channel types? I cannot seem to find any documentation confirming or disconfirming this.

EDIT: For the main text I just added tags that I had forgotten to add in the original post!

Cheers, Andrew

In the code snippet above, you create a custom info object, but don’t use it anywhere. So the channel Pupil Area is not yet defined in your raws[0] object. When you do print(epochs.channel_names), does the Pupil Area channel appear there?

2 Likes

Apologies! I omitted that code from the post and thanks for offering some insight!

Here’s the portion that was missing:

raws = []
for idx, df in enumerate(output[0]):
    baseline = df['TimeStamp'][0]
    pup = df['Pupil Area']
    eyex = df['X_Coord']
    eyey = df['Y_Coord']
    dat = np.array([eyex, eyey, pup])
    ano1 = mne.Annotations(onset = (output[6][idx]['Start'] - baseline)/1000,
            duration = (output[6][idx]['End'] - output[6][idx]['Start'])/1000, description=output[6][idx]['condition'])

    # ano1.append(onset = (output[9][idx]['TimeStamp'] - baseline)/1000,
    #        duration = 0.01, description= output[9][idx]['blockNo'])

    ano1.append(onset = (output[5][idx]['Start']- baseline)/1000,
                 duration = (output[5][idx]['End'] - output[5][idx]['Start'])/1000, description='BAD-Blink')
    
    tmp = mne.io.RawArray(dat, info)
    tmp.set_annotations(ano1)
    raws.append(tmp)
mne.io.concatenate_raws(raws)

#%%  Remove boundary annotations
anno_df = raws[0].annotations.to_data_frame()
rmv = anno_df.index[(anno_df['description'] == 'BAD boundary') | (anno_df['description'] == 'EDGE boundary')].tolist()
raws[0].annotations.delete(rmv)

so essentially raws[0] is the concatenated raw object over the list of individual raw objects loaded in using the info object. I have tested assigning a new variable (i.e. tst = mne. concatenate_raws(raws), epochs = mne.Epochs(tst) ) but it still provides the plotting error.

When I use print(epochs.ch_names) i receive ['Pupil Area'] as the output. As another check, I also printed the channel names when i don’t specify a channel in mne.Epochs() and I get ['eye_x', 'eye_y', 'Pupil Area'] which is the same as my n_channels list.

Hopefully, this clears up some more of my process.

Hi all,

Update on my progress so far. After going through some Github issue requests I saw issue #11322. This provided some insight into the issue, I added 'bio' (below) to the list of values and it seems that this was sufficient to solve the issue suggesting that this is an issue where evoked objects do not support plotting or the 'bio' data channel. The glossary also does not list ‘bio’ as a supported data channel which i suppose in hindsight i should’ve found first.

While I still need to manually adjust scalings and units as they are in microvolts this fix ‘seems’ to work. If an admin sees this again I’m happy to mark this as ‘solved’ if they request it so, but I’m unsure if I’m arriving at the right conclusion about what was going on here and if there are any plans to support 'bio' data channels in the future of MNE-python?

all_types = _DATA_CH_TYPES_SPLIT + ( 'misc', # from ICA 'emg', 'ref_meg', 'bio', #<- manually added 'bio' to documentation )

Cheers, Andrew