python - matplotlib 的二维插值频谱图差异的来源是什么?

标签 python matplotlib scipy interpolation

我正在尝试使用 scipy 的 inetrp2d 函数对从 matplotlib 获得的频谱图进行插值,但不知何故无法获得相同的频谱图。有资料here

实际的频谱图是:

enter image description here

插值后的频谱图是:

enter image description here

代码看起来不错,但即便如此,还是有问题。使用的代码是:

from __future__ import division
from matplotlib import ticker as mtick
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
import numpy as np
from bisect import bisect
from scipy import interpolate
from matplotlib.ticker import MaxNLocator
data = np.genfromtxt('spectrogram.dat', skiprows = 2, delimiter = ',')
pressure = data[:, 1] * 0.065
time = data[:, 0]
cax = plt.specgram(pressure * 100000, NFFT = 256, Fs = 50000, noverlap=4, cmap=plt.cm.gist_heat, zorder = 1)

f = interpolate.interp2d(cax[2], cax[1], cax[0], kind='cubic')
xnew = np.linspace(cax[2][0], cax[2][-1], 100)
ynew = np.linspace(cax[1][0], cax[1][-1], 100)
znew = 10 * np.log10(f(xnew, ynew))

fig = plt.figure(figsize=(6, 3.2))
ax = fig.add_subplot(111)
ax.set_title('colorMap')
plt.pcolormesh(xnew, ynew, znew, cmap=plt.cm.gist_heat)
# plt.colorbar()
plt.title('Interpolated spectrogram')
plt.colorbar(orientation='vertical')
plt.savefig('interp_spectrogram.pdf')

如何使用 Python 正确插值频谱图?

最佳答案

您的解决方案的关键在于此警告,您可能已经看到也可能没有看到:

RuntimeWarning: invalid value encountered in log10
    znew = 10 * np.log10(f(xnew, ynew))

如果您的数据实际上是一个幂,您希望将其日志明确查看为分贝幂,请先获取日志,然后再拟合样条曲线:

spectrum, freqs, t, im = cax
dB = 10*np.log10(spectrum)
#f = interpolate.interp2d(t, freqs, dB, kind='cubic') # docs for this recommend next line
f = interpolate.RectBivariateSpline(t, freqs,  dB.T) # but this uses xy not ij, hence the .T

xnew = np.linspace(t[0], t[-1], 10*len(t))
ynew = np.linspace(freqs[0], freqs[-1], 10*len(freqs)) # was it wider spaced than freqs on purpose?
znew = f(xnew, ynew).T

然后按照你的方式绘图:

decibels


上一个答案:

如果你只想plot on logscale , 使用 matplotlib.colors.LogNorm

znew = f(xnew, ynew) # Don't take the log here

plt.figure(figsize=(6, 3.2))
plt.pcolormesh(xnew, ynew, znew, cmap=plt.cm.gist_heat, norm=colors.LogNorm())

看起来像这样:

interpolated spectrogram

当然,当以对数刻度绘制时,它的值仍为负值。当值为负时,你的数据对你意味着什么应该决定你如何填写它。一个简单的解决方案是将这些值设置为最小的正值,它们将填充为黑色:

filled

关于python - matplotlib 的二维插值频谱图差异的来源是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32565343/

相关文章:

python - 使用 Sympy 返回自动导数

python - 使用 PyDev 在 Eclipse 中找不到 TODO 标签

python - matplotlib中2个y坐标之间的阴影区域

python - 无法手动关闭 matplotlib 绘图窗口

python - (Python) 使用 scikits bootstrap 估计回归参数置信区间

Python 无线局域网管理器

python - 如何列出从特定 IP 地址对维基百科进行的所有匿名(因此 IP 公开)编辑?

python - 完全隐藏x轴

python - 使用具有不同参数的 solve_ivp

python - 热图中的过渡线 - python