如何绘制一个频谱同样的方式,pylab的specgram()呢? [英] How do I plot a spectrogram the same way that pylab's specgram() does?

查看:4017
本文介绍了如何绘制一个频谱同样的方式,pylab的specgram()呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Pylab中, specgram()函数创建的幅度给定列表中的频谱,并自动为频谱创建一个窗口。

In Pylab, the specgram() function creates a spectrogram for a given list of amplitudes and automatically creates a window for the spectrogram.

我想生成频谱(瞬时功率由 PXX 给出),通过在其上运行的边缘检测器进行修改,然后绘制的结果。

I would like to generate the spectrogram (instantaneous power is given by Pxx), modify it by running an edge detector on it, and then plot the result.

(Pxx, freqs, bins, im) = pylab.specgram( self.data, Fs=self.rate, ...... )

问题是,每当我试图绘制修改 PXX 使用 imshow 甚至 NonUniformImage ,我碰到下面的错误消息。

The problem is that whenever I try to plot the modified Pxx using imshow or even NonUniformImage, I run into the error message below.

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/image.py:336: UserWarning:图片不支持非线性轴。
    warnings.warn(图像不支持非线性轴。)

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/image.py:336: UserWarning: Images are not supported on non-linear axes. warnings.warn("Images are not supported on non-linear axes.")

例如,code我的工作权利的一部分如下。

For example, a part of the code I'm working on right is below.

    # how many instantaneous spectra did we calculate
    (numBins, numSpectra) = Pxx.shape

    # how many seconds in entire audio recording
    numSeconds = float(self.data.size) / self.rate


    ax = fig.add_subplot(212)
    im = NonUniformImage(ax, interpolation='bilinear')

    x = np.arange(0, numSpectra)
    y = np.arange(0, numBins)
    z = Pxx
    im.set_data(x, y, z)
    ax.images.append(im) 
    ax.set_xlim(0, numSpectra)
    ax.set_ylim(0, numBins)
    ax.set_yscale('symlog') # see http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.set_yscale
    ax.set_title('Spectrogram 2')

实际问题

你怎么用matplotlib / pylab对数Y轴情节图像样的数据?

Actual Question

How do you plot image-like data with a logarithmic y axis with matplotlib/pylab?

推荐答案

使用令pColor pcolormesh pcolormesh 要快得多,但仅限于直线网格,其中为令pColor能够处理任意形状的细胞。 <罢工> specgram 使用 pcolormesh ,如果我没有记错。(它使用 imshow

Use pcolor or pcolormesh. pcolormesh is much faster, but is limited to rectilinear grids, where as pcolor can handle arbitrary shaped cells. specgram uses pcolormesh, if I recall correctly. (It uses imshow.)

作为一个简单的例子:

import numpy as np
import matplotlib.pyplot as plt

z = np.random.random((11,11))
x, y = np.mgrid[:11, :11]

fig, ax = plt.subplots()
ax.set_yscale('symlog')
ax.pcolormesh(x, y, z)
plt.show()

您所看到的差别是由于密谋原始值的 specgram 的回报。什么 specgram 实际上是绘制一个缩放版本。

The differences you're seeing are due to plotting the "raw" values that specgram returns. What specgram actually plots is a scaled version.

import matplotlib.pyplot as plt
import numpy as np

x = np.cumsum(np.random.random(1000) - 0.5)

fig, (ax1, ax2) = plt.subplots(nrows=2)
data, freqs, bins, im = ax1.specgram(x)
ax1.axis('tight')

# "specgram" actually plots 10 * log10(data)...
ax2.pcolormesh(bins, freqs, 10 * np.log10(data))
ax2.axis('tight')

plt.show()

注意,当我们使用绘制的事情 pcolormesh ,没有插值。 (这是 pcolormesh 的点的一部分 - 它只是载体,而不是矩形图像)

Notice that when we plot things using pcolormesh, there's no interpolation. (That's part of the point of pcolormesh--it's just vector rectangles instead of an image.)

如果您想对数尺度的东西,你可以使用 pcolormesh 吧:

If you want things on a log scale, you can use pcolormesh with it:

import matplotlib.pyplot as plt
import numpy as np

x = np.cumsum(np.random.random(1000) - 0.5)

fig, (ax1, ax2) = plt.subplots(nrows=2)
data, freqs, bins, im = ax1.specgram(x)
ax1.axis('tight')

# We need to explictly set the linear threshold in this case...
# Ideally you should calculate this from your bin size...
ax2.set_yscale('symlog', linthreshy=0.01)

ax2.pcolormesh(bins, freqs, 10 * np.log10(data))
ax2.axis('tight')

plt.show()

这篇关于如何绘制一个频谱同样的方式,pylab的specgram()呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆