# Issue with the time vector returned by $\tt signal.spectrogram$ function

I'm puzzled by some very simple concept with building up a spectrogram.

Here is a toy example of the issue:

import numpy as np
import scipy
from scipy import signal
import matplotlib.pyplot as plt

f0 = 5
t = 2
fs = 250
N = t*fs
t = np.linspace(0, t, N, endpoint=False)
x = np.sin(2*scipy.pi*f0*t)
f, t, Sxx = signal.spectrogram(x, fs)
plt.pcolormesh(t, f, Sxx)
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')
plt.show()

What I get for t puzzles me, I get [0.512,1.408]. I would expect to get an array starting from 0.0 to 2.0 seconds long - so if I want to see the power spectrum density in 1.8 seconds I could easily do so.

I probably miss something pretty basic, so it would be great if someone could shed some light on this.

Mike.

• Does using 0.0 (float) as start point give a different result than 0 (integer)? – Juancho Jun 9 '17 at 13:47

The default parameters of signal.spectrogram are:

nperseg = 256
noverlap = nperseg/8 = 32

This means that:

• The length of analysis window is $256$ samples ($256/250 = 1.024$ second)
• The overlap between consecutive windows is $32$ samples ($32/250 = 0.128$ second)

The timestamps returned by signal.spectrogram correspond to the centres of a window. So in your case, the first timestamp should be at $256/2 = 128$ samples, which is equal to $0.512$ seconds given a sampling frequency of $250 \mathrm{Hz}$.

The beginning of the next window will be shifted by $256-32 = 224$ samples ($32$ is an overlap), so its centre will be at $224 + 128 = 352$ samples (which corresponds to $1.408$ second). The end of the second window is at $480$ samples, so there is not enough data to process more frames.

This explains why your time vector is [0.512, 1.408].

Here is a graphical explanation:

So if you want to achieve a specific frequency spacing, you must modify the nperseg and noverlap parameters.