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

python,matplotlib:specgram数据数组值与specgram plot不匹配,python,arrays,matplotlib,spectrogram,Python,Arrays,Matplotlib,Spectrogram,我正在使用matplotlib.pyplot.specgram和matplotlib.pyplot.pcolormesh绘制地震信号的频谱图 背景信息-使用pcolormesh的原因是,我需要在spectragram数据阵列上进行算术运算,然后重新生成频谱图(对于三分量地震图-东部、北部和垂直-我需要计算出水平谱幅度,并将垂直谱除以水平谱)。使用谱图阵列数据比使用单个振幅谱更容易做到这一点 我发现在做了我的算术之后,光谱图的曲线图有意想不到的值。进一步调查发现,与使用pyplot.pcolorm

我正在使用matplotlib.pyplot.specgram和matplotlib.pyplot.pcolormesh绘制地震信号的频谱图

背景信息-使用pcolormesh的原因是,我需要在spectragram数据阵列上进行算术运算,然后重新生成频谱图(对于三分量地震图-东部、北部和垂直-我需要计算出水平谱幅度,并将垂直谱除以水平谱)。使用谱图阵列数据比使用单个振幅谱更容易做到这一点

我发现在做了我的算术之后,光谱图的曲线图有意想不到的值。进一步调查发现,与使用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()
看起来和故事情节不同

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”数据数组(即,每个片段的谱图数据值)由第一种方法生成,并在第二种方法中重复使用

有人知道为什么会这样吗

另外,我意识到我的NFFT值不是一个平方数,但在我编码的这个阶段它并不重要


p.p.S.我不知道“imN”数组(pyplot.specgram返回的第四个变量)是什么以及它的用途……

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

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
的功能:

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()

改用对数色标 或者,我们可以在图像上使用对数范数,并获得类似的结果,但更清楚地传达颜色值在对数刻度上:

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()

imshow
vs
pcolormesh
最后,请注意,我们展示的示例没有应用插值,而原始的
specgram
plot应用了插值
specgram
使用
imshow
,而我们一直在使用
pcolormesh
进行绘图。在这种情况下(规则栅格间距),我们可以使用其中一种

在这种情况下,
imshow
pcolormesh
都是非常好的选择。但是,如果您使用的是大型阵列,
imshow
将具有显著更好的性能。因此,你可以考虑使用它,即使你不想要插值(例如<代码>插值=最近的< /COD>关闭插值)。 例如:

extent = [xbins.min(), xbins.max(), ybins.min(), ybins.max()]

fig, ax = plt.subplots()
mesh = ax.imshow(values, extent=extent, origin='lower', aspect='auto',
                 cmap='gist_earth', norm=LogNorm())

ax.axis('tight')
ax.set(title='Log Normalized Plot of Values')
fig.colorbar(mesh)

plt.show()

它们有何不同?你能举个例子吗?你能提供一个能让其他人重现你问题的
trN
示例吗?太棒了,非常感谢,这解释了一切,现在我明白了。我觉得这个答案应该有数百次投票,它为我节省了数小时的时间。需要为Fs:specgram(x,Fs=1,cmap='gist\u earth'添加值)