raphaelvallat / yasa

YASA (Yet Another Spindle Algorithm): a Python package to analyze polysomnographic sleep recordings.
https://raphaelvallat.com/yasa/
BSD 3-Clause "New" or "Revised" License
425 stars 115 forks source link

Error when using mne raw to get power spectrum. I want to use edf imported to mne in (A). #49

Closed paulokanda closed 2 years ago

paulokanda commented 2 years ago

Dear Professor Vallat,

First of all many thanks for taking the time to bring us this very usefull yasa script.

I already use edf in mne in some tasks. Now I'm learning yasa to get information from resting state awake EEG without events.

I've managed to import and use mne raw in this tutorial:

08_bandpower.ipynb .

but when I try this very interesting tutorial: https://raphaelvallat.com/bandpower.html (A)

I receive an error:


sample_data_raw_file = 'C:\\000_tmp\\00000034_s001_t002.edf'  
raw = mne.io.read_raw_edf(sample_data_raw_file, preload=True, verbose=False)

sns.set(font_scale=1.2)
# data =yasa.bandpower(raw.copy().pick_channels(['F3']), bandpass=True)
# Define sampling frequency and time vector

data = raw[:][0]   #to get the numpy array. 
sf = 100.
time = np.arange(data.size) / sf

# Plot the signal
fig, ax = plt.subplots(1, 1, figsize=(12, 4))
plt.plot(time, data, lw=1.5, color='k')
plt.xlabel('Time (seconds)')
plt.ylabel('Voltage')
# plt.xlim([time.min(), time.max()])
plt.xlim([time.min(), time.max()])
plt.title('N3 sleep EEG data (F3)')
sns.despine()

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-148-cf49d519d2c3> in <module>
      9 # Plot the signal
     10 fig, ax = plt.subplots(1, 1, figsize=(12, 4))
---> 11 plt.plot(time, data, lw=1.5, color='k')
     12 plt.xlabel('Time (seconds)')
     13 plt.ylabel('Voltage')

c:\python\python38\lib\site-packages\matplotlib\pyplot.py in plot(scalex, scaley, data, *args, **kwargs)
   3017 @_copy_docstring_and_deprecators(Axes.plot)
   3018 def plot(*args, scalex=True, scaley=True, data=None, **kwargs):
-> 3019     return gca().plot(
   3020         *args, scalex=scalex, scaley=scaley,
   3021         **({"data": data} if data is not None else {}), **kwargs)

c:\python\python38\lib\site-packages\matplotlib\axes\_axes.py in plot(self, scalex, scaley, data, *args, **kwargs)
   1603         """
   1604         kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
-> 1605         lines = [*self._get_lines(*args, data=data, **kwargs)]
   1606         for line in lines:
   1607             self.add_line(line)

c:\python\python38\lib\site-packages\matplotlib\axes\_base.py in __call__(self, data, *args, **kwargs)
    313                 this += args[0],
    314                 args = args[1:]
--> 315             yield from self._plot_args(this, kwargs)
    316 
    317     def get_next_color(self):

c:\python\python38\lib\site-packages\matplotlib\axes\_base.py in _plot_args(self, tup, kwargs, return_kwargs)
    499 
    500         if x.shape[0] != y.shape[0]:
--> 501             raise ValueError(f"x and y must have same first dimension, but "
    502                              f"have shapes {x.shape} and {y.shape}")
    503         if x.ndim > 2 or y.ndim > 2:

ValueError: x and y must have same first dimension, but have shapes (202000,) and (1, 202000)

Could you show me a path to follow?

Thanks in advance Paulo Kanda University of São Paulo

raphaelvallat commented 2 years ago

Hi @paulokanda,

Thanks for your message. You need to use np.squeeze(data) to ensure that time and data are both one-dimensional (by default data is 2D, i.e. data.shape = (n_channels, n_times)).

Hope this helps, Thanks, Raphael

paulokanda commented 2 years ago

I think that yasa is considering index as a value because

I reduced raw (from edf+) to one channel:

raw1 = raw.pick_channels(['F3']) data = raw1.get_data() etc...

data.shape (1, 80800)

raw_df1.head()

           time | F3

0 0 | 1.016440e-13 1 10 | -3.411143e-01 2 20 | -3.844158e-01 3 30 | -4.245883e-01 4 40 | -5.764858e-01

data array([[ 1.01643954e-19, -3.41114305e-07, -3.84415789e-07, ..., 3.68912472e-06, 3.24150894e-06, -1.01643954e-19]])

error remains:

ValueError: x and y must have same first dimension, but have shapes (80800,) and (1, 80800)

It doesnot happen when plotting with other methods in mne.

Is it an yasa bug? Please what I'm missing? Thanks in advance.

raphaelvallat commented 2 years ago

Hi @paulokanda,

This is not a YASA bug since your code does not include any YASA functions. Rather, the issue is that when you use raw.get_data() with a single channel in MNE, you still end up with a two-dimensional array, even though you have only one channel. The output dimension of the array is (n_channels, n_samples). However, the time vector that we use in the matplotlib plt.plot() function is one-dimensional. The following should work:

plt.plot(time, np.squeeze(data))

Thanks, Raphael

paulokanda commented 2 years ago

Thank you for your time and clear explanation.