Wrong spectrogram when using scipy.signal.spectrogram

You should use one of the non-linear colormap in your pcolormesh function.

Try to set norm=matplotlib.colors.LogNorm(vmin=np.amin(spectrogram), vmax=np.amax(spectrogram))

Or norm=matplotlib.colors.PowerNorm(gamma=0.5).

See https://matplotlib.org/stable/tutorials/colors/colormapnorms.html for more info.


The default scaling mode for specgram is 'dB' (from the specgram docs)

scale : [ ‘default’ | ‘linear’ | ‘dB’ ] The scaling of the values in the spec. ‘linear’ is no scaling. ‘dB’ returns the values in dB scale. When mode is ‘psd’, this is dB power (10 * log10). Otherwise this is dB amplitude (20 * log10). ‘default’ is ‘dB’ if mode is ‘psd’ or ‘magnitude’ and ‘linear’ otherwise. This must be ‘linear’ if mode is ‘angle’ or ‘phase’.

mode : [ ‘default’ | ‘psd’ | ‘magnitude’ | ‘angle’ | ‘phase’ ] What sort of spectrum to use. Default is ‘psd’, which takes the power spectral density. ‘complex’ returns the complex-valued frequency spectrum. ‘magnitude’ returns the magnitude spectrum. ‘angle’ returns the phase spectrum without unwrapping. ‘phase’ returns the phase spectrum with unwrapping.

To achieve similar results with pcolormesh you will need to scale the data equivalently.

plt.pcolormesh(times, frequencies, 10*np.log10(spectrogram))

I don't think the pcolormesh example is correct in its scaling. You can clearly see the carrier in the example but the added noise signal is not visible.