Python 使用scipy.signal.spectrogram时出现错误的频谱图

Python 使用scipy.signal.spectrogram时出现错误的频谱图,python,audio,scipy,spectrogram,Python,Audio,Scipy,Spectrogram,当我使用matplotlib中的plt.specgram(使用以下代码)时,生成的光谱图是正确的 import matplotlib.pyplot as plt from scipy import signal from scipy.io import wavfile import numpy as np sample_rate, samples = wavfile.read('.\\Wav\\test.wav') Pxx, freqs, bins, im = plt.specgram(sa

当我使用matplotlib中的plt.specgram(使用以下代码)时,生成的光谱图是正确的

import matplotlib.pyplot as plt
from scipy import signal
from scipy.io import wavfile
import numpy as np

sample_rate, samples = wavfile.read('.\\Wav\\test.wav')

Pxx, freqs, bins, im = plt.specgram(samples[:,1], NFFT=1024, Fs=44100, noverlap=900)

但是,如果我使用中给出的示例代码和以下代码生成光谱图,我会得到如下结果:

import matplotlib.pyplot as plt
from scipy import signal
from scipy.io import wavfile
import numpy as np

sample_rate, samples = wavfile.read('.\\Wav\\test.wav')

frequencies, times, spectrogram = signal.spectrogram(samples[:,1],sample_rate,nfft=1024,noverlap=900, nperseg=1024)

plt.pcolormesh(times, frequencies, spectrogram)
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')

为了调试正在发生的事情,我尝试使用第一种方法生成的
Pxx
freqs
bins
,然后使用第二种方法绘制数据:

plt.pcolormesh(bins, freqs, Pxx)
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')

生成的图与第二种方法生成的图几乎相同。 所以,
scipy.signal.spectrogram
似乎并没有问题。问题在于我们绘制图表的方式。我想知道
plt.pcolormesh
是否是绘制光谱图的正确方法,尽管该方法在


有人问过类似的问题,但这个问题还没有解决办法。

specgram的默认缩放模式是“dB”(来自specgram文档)

比例:[“默认”|“线性”|“dB”] 规范“线性”中的值的缩放不是缩放“dB”以dB比例返回值。当模式为“psd”时,这是dB功率(10*log10)。否则,这是dB振幅(20*log10)。'如果模式为“psd”,则默认值为“dB”,否则为“幅值”和“线性”。如果模式为“角度”或“相位”,则必须为“线性”

模式:[“默认值”|“psd”|“幅值”|“角度”|“相位”] 使用哪种频谱默认值为“psd”,它采用功率谱密度复数“返回复数频谱。”“震级”返回震级谱angle'返回无需展开的相位谱。'“相位”返回带展开的相位谱

要使用
pcolormesh
获得类似的结果,您需要等效地缩放数据

plt.pcolormesh(times, frequencies, 10*np.log10(spectrogram))
我认为pcolormesh示例的缩放不正确。您可以清楚地看到示例中的载波,但添加的噪声信号不可见。

使用此选项:

plt.pcolormesh(times, frequencies, spectrogram, norm = matplotlib.colors.Normalize(0,1))
这将在打印之前规范化数据,以便您可以正确地可视化颜色。上的文档说明“通常使用Colormap实例将数据值(浮动)从间隔[0,1]转换为相应Colormap表示的RGBA颜色。”
如果您的值超出此范围,它可能会将其打印为深色(我相信)。

我尝试了此方法,但没有效果,它只打印黄色背景,而不是我最初得到的紫色背景。你能发布你的整个光谱图生成代码吗?为什么我们在这里乘以10?我去掉了它,它仍然有效。这就是我们用分贝来表示能量的方式。看见通常我们使用10作为比例因子,但有时,当我们谈论功率传递时(或者更准确地说,我们使用需要平方才能获得功率的量),我们使用比例因子20。换句话说,它不乘以10就可以工作,但它并不代表一个有效的数量。这是一个有一年历史的问题,但是这个问题上的scipy文档页面仍然没有改变。