2
votes

I have some 64 channel EEG data sampled at 256Hz and I'm trying to conduct a time frequency analysis for each channel and plot a spectrogram.

The data is stored in a numpy 3d array, where one of the dimensions has length 256, each element containing a microvolt reading over all sampled time points (total length is 1 second for each channel of data).

To be clear: my 3D array is 64*256*913 (electrode * voltages * trial). Trial is just a single trial of an experiment. So what I want to do is take a single electrode, from a single trial, and the entire 1D voltage vector and creating a time-frequency spectrogram. So I want to create a spectrogram plot from data[0,:,0] for example.

For each eletrode, I want a plot where the y axis is frequency, x axis is time, and colour/intensity is power

I have tried using this in python:

from matplotlib.pyplot import specgram
#data = np.random.rand(256)
specgram(data, NFFT=256, Fs=256)

This gives me something that looks like this:

enter image description here

Right off the bat this looks incorrect to me because the axis ranges are incorrect

Furthermore, when I run the same code for all EEG channels, over all of my data, I end up with the exact same plot (even though I have verified that the data is different for each)

I'm pretty new to signal processing, is there somewhere that I went wrong in either how my data is laid out or how I used my function?

1
Could you tell something more about data? I assume that one of your axis is voltage, second is time and third one is channel - so I guess that you should take one channel, and forget about time, because period between samples is constant. For specgram you should use 1-D array or sequence, so I think that problem might be here.Grysik
Sorry for not being clear. I've updated the question. Basically the 3 dimensions of my 3D array are electrode * voltage * trial. I am taking a 1D array (voltage) for a single electrode in a single trial and wanting a spectrogram from it. So yes, I am plotting 1D arraysSimon
Try something likespecgram(data, NFFT=64, noverlap=63, Fs=256) If you have only 256 samples and you do a FFT with 256 samples, you'll have no resolution in timeDietrich
That did the trick, thanks! If you post it as an answer I can accept itSimon

1 Answers

0
votes

From the documentation for the specgram function:

Plot a spectrogram.

Call signature:

specgram(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, window=mlab.window_hanning, noverlap=128, cmap=None, xextent=None, pad_to=None, sides='default', scale_by_freq=None, mode='default', scale='default', **kwargs)

Compute and plot a spectrogram of data in x. Data are split into NFFT length segments and the spectrum of each section is computed. The windowing function window is applied to each segment, and the amount of overlap of each segment is specified with noverlap. The spectrogram is plotted as a colormap (using imshow).

x: 1-D array or sequence Array or sequence containing the data

It looks like your problem is that you're not passing in 1-D data. Try:

from matplotlib.pyplot import specgram
specgram(data.flatten(), NFFT=256, Fs=256)