Matplotlib spectral graph intensity designation (colorbar)

I use the matplotlib specgram function to create a spectrogram. I tried to turn on the color bar to the right of the spectrogram to give an idea of ​​the db-to-color display.

For some reason, the dBs indicated by the color bar do not make sense.

Perhaps I did not generate the colorbar correctly? Perhaps there is some kind of parameter that I need to pass to the specgram?

The signal that I generate is a 1 kHz sine wave, 2 VDC. current taken at 32 Hz.

I expect the dark red peak on the spectrogram to correspond to 0 dB (which means that + 1V is my reference)

Can anyone understand what is wrong with my approach?

 def plot_specgram(data, title='', x_label='', y_label='', fig_size=None): fig = plt.figure() if fig_size != None: fig.set_size_inches(fig_size[0], fig_size[1]) ax = fig.add_subplot(111) ax.set_title(title) ax.set_xlabel(x_label) ax.set_ylabel(y_label) pxx, freq, t, cax = plt.specgram(data, Fs=32000) fig.colorbar(cax).set_label('Intensity [dB]') plot_specgram(a,title='Spectrogram', x_label='time (in seconds)', y_label='frequency', fig_size=(14,8)) 

This is what I get as a result of the spectrogram:

resulting plot

+5
source share
1 answer

First of all, put your a vector, since it seems to have some kind of harmonics.

This is a bit trial version and an error, but it seems to lead to the correct scaling:

 NFFT = 256 ax.specgram(x/(NFFT/2), NFFT=NFFT, Fs=fs, mode='magnitude', window=plt.window_none) 

Using a window seems to lose about 1/2 of its peak power, you can, of course, adjust for that.

A complete example where I limited the dynamic range to 40 dB (as an example, if you want to hide small things).

 import numpy as np import pylab as plt # generate a 1kHz sine wave fs = 32e3 t = np.arange(0, 15, 1.0/fs) f0 = 1e3 A = 1 x = A*np.sin(2*np.pi*f0*t) fig, ax = plt.subplots() cmap = plt.get_cmap('viridis') vmin = 20*np.log10(np.max(x)) - 40 # hide anything below -40 dBc cmap.set_under(color='k', alpha=None) NFFT = 256 pxx, freq, t, cax = ax.specgram(x/(NFFT/2), Fs=fs, mode='magnitude', NFFT=NFFT, noverlap=NFFT/2, vmin=vmin, cmap=cmap, window=plt.window_none) fig.colorbar(cax) print np.max(pxx) # should match A 

final image

+3
source

Source: https://habr.com/ru/post/1207966/


All Articles