I have calculated the STFT with scipy python library:

f_spec, t_spec, Spectro= sc.signal.spectrogram(My_Signal, fs=1.0, window='hamming', nperseg=180,
                        noverlap=None, nfft=2048, detrend=False, return_onesided=False, scaling='density',
                        axis=-1, mode='complex')

I wanted to get the same result as spectrogram function of MATLAB and now I want to calcluate its PSD in dB. In fact I have found several expression in internet such as :


or :

PSD = 10*log10(abs(Spectro))

I am not sure what to use can any one help me?


In general, if you have complex spectrum and need PSD in dB the mathematical equation is

$$P_{xx} = 20\cdot\log_{10}|X_{x}|,$$ where $P_{xx}$ is your PSD in dB and $X_{x}$ is your complex STFT spectrum (variable Spectro in your case).

In SciPy documentation for scipy.signal.spectrogram is mentioned, that you can compute spectrogram with different modes (‘psd’, ‘complex’, ‘magnitude’, ‘angle’, ‘phase’). You have chosen mode='complex', which returns complex STFT, so you should get PSD from equation above. If you have chosen mode='psd' you would get PSD e.g. $S_{xx}$ (Spectro in your case) in the first place and to convert it to dB your equation is $$P_{xx} = 10\cdot\log_{10}S_{xx}.$$

However, if you want to plot same spectrogram as the MATLAB one I would choose equivalent matplotlib.pyplot.specgram, which is very similar and you can plot PSD already in dB with this tool.

  • $\begingroup$ Thank you it is very clear! $\endgroup$ – baddy Jan 16 at 6:16

I normally use the Welch method to calculate and plot the PSD of a signal.

signal_f, signal_psd = sp.welch(signal, sampling_frequency, return_onesided=False, nperseg=256)
signal_f = np.fft.fftshift(signal_f)
signal_psd = np.fft.fftshift(signal_psd)

plt.semilogy(signal_f, signal_psd, label = 'PSD')

Maybe it helps you!

  • $\begingroup$ can I use the welch method without overlapping because I aim to calculate the PSD in dB without overlapping $\endgroup$ – baddy Jan 16 at 6:15
  • $\begingroup$ Yes, although I always used it on default settings. I just tried with noverlap = 0. Refer here, docs.scipy.org/doc/scipy-0.14.0/reference/generated/…. The results are slightly different but not much. $\endgroup$ – gklearning Jan 16 at 10:51

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.