15

The functions
spicy.signal.spectrogram:https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.spectrogram.html
and
spicy.signal.stft:https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.stft.html
seem to do a very similar thing.

What is the difference between the two functions?

Aarif
  • 1,595
  • 3
  • 17
  • 29
user7468395
  • 1,299
  • 2
  • 10
  • 23

1 Answers1

20

Tl;dr: If I write it with the ouput given by the SciPy documentation: Sxx = Zxx ** 2

Explanation: Spectrogram and Short Time Fourier Transform are two different object, yet they are really close together.

The short-time Fourier transform (STFT), is a Fourier-related transform used to determine the sinusoidal frequency and phase content of local sections of a signal as it changes over time. In practice, the procedure for computing STFTs is to divide a longer time signal into shorter segments of equal length and then compute the Fourier transform separately on each shorter segment. This reveals the Fourier spectrum on each shorter segment. One then usually plots the changing spectra as a function of time. Wikipedia

On the other hand,

A spectrogram is a visual representation of the spectrum of frequencies of a signal as it varies with time. Wikipedia

The spectrogram basically cuts your signal in small windows, and display a range of colors showing the intensity of this or that specific frequency. Exactly as the STFT. In fact it's using the STFT.

Now, for the difference, by definition, the spectrogram is squared magnitude of the short-time Fourier transform (STFT) of the signal s(t):

spectrogram(t, w) = |STFT(t, w)|^2

The example shown at the bottom of the scipy.signal.stft page shows:

>>> plt.pcolormesh(t, f, np.abs(Zxx), vmin=0, vmax=amp)

It's working and you can see a color scale. But it's a linear one, because of the abs operation.

In reality, to get the real spectrogram, one should write:

>>> plt.pcolormesh(t, f, Zxx ** 2, vmin=0, vmax=amp)
ggrelet
  • 1,071
  • 7
  • 22
  • 1
    Minor nitpick, but shouldn't that last term be the magnitude squared, and not just squared? – Eric C. Jan 24 '22 at 14:41
  • I am not sure I understand your question perfectly but in the case of the L2 norm, if I write X = [x1, x2, x3,...] as a vector, X^2 = X.X (dotproduct) = |x1| * |x1| + |x2| * |x2| + |x3| * |x3| +... = |x1|^2 + |x2|^2 + |x3|^2 +... = |X|^2 So in the end it's the same! – ggrelet Jan 25 '22 at 09:05
  • 2
    My question is if the data is complex. You mention the spectrogram as the magnitude squared of the STFT but then show in the pcolormesh command just taking Zxx ** 2, whereas I think maybe it should be np.abs(Zxx)**2? – Eric C. Jan 25 '22 at 14:36
  • Both functions have an optional parameter to chose what is the output, for `spectrogram`: `scaling{ ‘density’, ‘spectrum’ }`, for `stft`: `scaling: {‘spectrum’, ‘psd’}`, so both amplitude and power can be directly obtained in both functions. I believe `spectrogram` has no inverse to reconstruct the signal, while `stft` has `istft`. The reason might be [how overlap is managed](https://www.dsprelated.com/freebooks/sasp/Mathematical_Definition_STFT.html#19930). – mins Mar 21 '23 at 16:18