Python - time frequency spectrogram

Simon picture Simon · Aug 7, 2015 · Viewed 8.9k times · Source

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?

Answer

Joel picture Joel · Aug 7, 2015

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)