python,matplotlib:specgram数据数组值与specgram plot不匹配

时间:2015-12-08 12:34:19

标签: python arrays matplotlib spectrogram

我使用matplotlib.pyplot.specgram和matplotlib.pyplot.pcolormesh来制作地震信号的频谱图。

背景信息 - 使用pcolormesh的原因是我需要在光谱图数据阵列上进行算术,然后重新绘制得到的谱图(对于三分量地震图 - 东,北和垂直 - 我需要工作超出水平光谱幅度并用水平光谱划分垂直光谱。使用频谱图阵列数据比使用单个幅度光谱更容易做到这一点

我发现进行算术运算后的频谱图有意外的值。经过进一步调查后发现,与使用pyplot.pcolormesh制作的频谱图和pyplot.specgram方法返回的数据数据相比,使用pyplot.specgram方法制作的频谱图具有不同的值。两个图/数组都应该包含相同的值,我无法理解为什么它们没有。

实施例:

的情节
plt.subplot(513)
PxN, freqsN, binsN, imN = plt.specgram(trN.data, NFFT = 20000, noverlap = 0, Fs = trN.stats.sampling_rate, detrend = 'mean', mode = 'magnitude')
plt.title('North')
plt.xlabel('Time [s]')
plt.ylabel('Frequency [Hz]')
plt.clim(0, 150)
plt.colorbar()
#np.savetxt('PxN.txt', PxN)

的情节有所不同
plt.subplot(514)
plt.pcolormesh(binsZ, freqsZ, PxN)
plt.clim(0,150)
plt.colorbar()

即使“PxN”数据数组(即每个分段的频谱图数据值)由第一种方法生成并在第二种方法中重复使用。

有人知道为什么会这样吗?

P.S。我意识到我对NFFT的价值不是一个平方数,但在我编码的这个阶段它并不重要。

P.P.S。我不知道“imN”数组(来自pyplot.specgram的第四个返回变量)是什么以及它用于什么....

1 个答案:

答案 0 :(得分:5)

首先,让我们展示一下您所描述的内容的一个例子,以便其他人

 private IList<Beneficiary> _beneficiaryList;
    public IList<Beneficiary> BeneficiaryList
    {
        get { return _beneficiaryList; }
        set { _beneficiaryList= value; RaisePropertyChanged(() => BeneficiaryList); }
    }

 public ICommand UpdateBeneficiary=> new MvxCommand<Beneficiary>(item =>
    {
        //item is of type Beneficiary
        //But I do not know which index of BeneficiaryList to update
    });

enter image description here

幅度差异

您会立即注意到绘制值的大小差异。

默认情况下,import numpy as np import matplotlib.pyplot as plt np.random.seed(1) # Brownian noise sequence x = np.random.normal(0, 1, 10000).cumsum() fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(8, 10)) values, ybins, xbins, im = ax1.specgram(x, cmap='gist_earth') ax1.set(title='Specgram') fig.colorbar(im, ax=ax1) mesh = ax2.pcolormesh(xbins, ybins, values, cmap='gist_earth') ax2.axis('tight') ax2.set(title='Raw Plot of Returned Values') fig.colorbar(mesh, ax=ax2) plt.show() 不会绘制它返回的“原始”值。相反,它将它们缩放为分贝(换句话说,它绘制了振幅的plt.specgram)。如果您不想扩展内容,则需要指定10 * log10。然而,对于频率成分的观察,对数尺度最有意义。

考虑到这一点,让我们模仿scale="linear"做什么:

specgram

enter image description here

使用日志颜色比例

或者,我们可以在图像上使用日志规范并获得类似的结果,但是更清楚地传达颜色值在对数范围内:

plotted = 10 * np.log10(values)

fig, ax = plt.subplots()
mesh = ax.pcolormesh(xbins, ybins, plotted, cmap='gist_earth')

ax.axis('tight')
ax.set(title='Plot of $10 * log_{10}(values)$')
fig.colorbar(mesh)

plt.show()

enter image description here

from matplotlib.colors import LogNorm fig, ax = plt.subplots() mesh = ax.pcolormesh(xbins, ybins, values, cmap='gist_earth', norm=LogNorm()) ax.axis('tight') ax.set(title='Log Normalized Plot of Values') fig.colorbar(mesh) plt.show() vs imshow

最后,请注意我们显示的示例没有应用插值,而原始的pcolormesh绘图确实如此。 specgram使用specgram,而我们一直在使用imshow进行策划。在这种情况下(常规网格间距)我们可以使用其中之一。

在这种情况下,pcolormeshimshow都是非常好的选择。但是,如果您正在使用大型数组,pcolormesh将具有明显更好的性能。因此,您可以考虑使用它,即使您不想插值(例如imshow关闭插值)。

举个例子:

interpolation='nearest'

enter image description here