7

I am following the tutorial example at scipy.signal.spectrogram. Is it possible to limit the frequencies we want to calculate the spectogram for, let's say in the range 1000-2000Hz. As per FFT, we will get it for half of the sampling frequencies. If not then can I slice the outputs to get a 3D matrix of t,f,Sxx where I limit the frequencies to say 1000-2000 Hz? Usage in my case is that my signal contains only certain range of frequencies and keeping all will be costly for my analysis.

SleuthEye
  • 14,379
  • 2
  • 32
  • 61
gmatharu
  • 83
  • 1
  • 8

1 Answers1

7

Unless you were to analyse a very small percentage of the frequency spectrum, computing the entire spectrum with the FFT (and throwing away the parts you don't want) is usually still a fairly efficient way to obtain a partial spectrum.

You can then find the frequencies of interest in f using numpy.where (following this answer by askewchan). The next step would then be to simply slice the output, extracting the desired frequency values in the 1D-array f and associated power spectrum values in the 2D-array Sxx. This can be done as follows:

...
f, t, Sxx = signal.spectrogram(x, fs)

fmin = 1000 # Hz
fmax = 2000 # Hz
freq_slice = np.where((f >= fmin) & (f <= fmax))

# keep only frequencies of interest
f   = f[freq_slice]
Sxx = Sxx[freq_slice,:][0]
SleuthEye
  • 14,379
  • 2
  • 32
  • 61
  • [SleuthEye](https://stackoverflow.com/users/2994596/sleutheye), Thanks, that works perfectly fine, from your answer it seems that I can calculate the stft for certain range of frequency spectrum efficiently using some other method than throwing away some information i.e lets say If I want to limit my frequency range to 2000 HZ, can I limit them somehow with **spectrogram** function. FYI, I am trying to do time-frequency analysis of a signal. – gmatharu Jan 05 '18 at 19:17
  • 1
    It is indeed possible to limit the frequency range, but this wouldn't be done directly with `spectrogram`. One way would involve downsampling the input signal (and possibly also baseband shifting if `fmin>0`), but this process has a non-negligible cost (in complexity and in processing time), so would usually only be beneficial if the downsampling factor is sufficiently large. Another way would use the [Goertzel algorithm](https://en.wikipedia.org/wiki/Goertzel_algorithm) instead of FFT, but again you'd gain something only if looking at a tiny portion of the spectrum. – SleuthEye Jan 05 '18 at 20:30
  • Thanks you [SleuthEye](https://stackoverflow.com/users/2994596/sleutheye) for providing details about Goertzel algo, It will definitely help. your answer provides answer, in addition to what else can be done. I will try to follow this practice. – gmatharu Jan 05 '18 at 20:42
  • Unfortunately "still a fairly efficient way" is less and less true when the number of dimensions increases. – uhoh Sep 10 '20 at 11:09