gpt4 book ai didi

python - 在 specgram matplotlib 中切割未使用的频率

转载 作者:太空狗 更新时间:2023-10-29 20:38:48 27 4
gpt4 key购买 nike

我有一个采样率为 16e3 的信号,其频率范围为 125 到 1000 Hz。因此,如果我绘制一个频谱图,我会得到一个非常小的颜色范围,因为所有未使用的频率。

我尝试通过设置 ax 限制来修复它,但这不起作用。

有什么方法可以切断未使用的频率或用 NaN 替换它们?

将数据重新采样为 2e3 将不起作用,因为在 125 Hz 以下仍有一些未使用的频率。

感谢您的帮助。

最佳答案

specgram() 正在为您完成所有工作。如果你在 axes.py 中查看 specgram 函数,你可以看到它是如何工作的。原函数在我电脑上的Python27\Lib\site-packages\matplotlib\axes.py

    <snip>  
Pxx, freqs, bins = mlab.specgram(x, NFFT, Fs, detrend,
window, noverlap, pad_to, sides, scale_by_freq)

Z = 10. * np.log10(Pxx)
Z = np.flipud(Z)

if xextent is None: xextent = 0, np.amax(bins)
xmin, xmax = xextent
freqs += Fc
extent = xmin, xmax, freqs[0], freqs[-1]
im = self.imshow(Z, cmap, extent=extent, **kwargs)
self.axis('auto')

return Pxx, freqs, bins, im

您可能必须以此为模型制作您自己的函数,并裁剪 Pxx 数据以满足您的需要。

    Pxx, freqs, bins = mlab.specgram(x, NFFT, Fs, detrend,
window, noverlap, pad_to, sides, scale_by_freq)
# ****************
# create a new limited Pxx and freqs
#
# ****************
Z = 10. * np.log10(Pxx)
Z = np.flipud(Z)

Pxx 是一个二维数组,形状为 (len(freqs),len(bins)

>>> Pxx.shape
(129, 311)
>>> freqs.shape
(129,)
>>> bins.shape
(311,)
>>>

这将限制 Pxx 和 freqs

Pxx = Pxx[(freqs >= 125) & (freqs <= 1000)]
freqs = freqs[(freqs >= 125) & (freqs <= 1000)]

这是一个完整的解决方案 - my_specgram() - 与图库中的 specgram_demo 一起使用

from pylab import *
from matplotlib import *


# 100, 400 and 200 Hz sine 'wave'
dt = 0.0005
t = arange(0.0, 20.0, dt)
s1 = sin(2*pi*100*t)
s2 = 2*sin(2*pi*400*t)
s3 = 2*sin(2*pi*200*t)

# create a transient "chirp"
mask = where(logical_and(t>10, t<12), 1.0, 0.0)
s2 = s2 * mask

# add some noise into the mix
nse = 0.01*randn(len(t))

x = s1 + s2 + +s3 + nse # the signal
NFFT = 1024 # the length of the windowing segments
Fs = int(1.0/dt) # the sampling frequency

# modified specgram()
def my_specgram(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none,
window=mlab.window_hanning, noverlap=128,
cmap=None, xextent=None, pad_to=None, sides='default',
scale_by_freq=None, minfreq = None, maxfreq = None, **kwargs):
"""
call signature::

specgram(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none,
window=mlab.window_hanning, noverlap=128,
cmap=None, xextent=None, pad_to=None, sides='default',
scale_by_freq=None, minfreq = None, maxfreq = None, **kwargs)

Compute a spectrogram of data in *x*. Data are split into
*NFFT* length segments and the PSD of each section is
computed. The windowing function *window* is applied to each
segment, and the amount of overlap of each segment is
specified with *noverlap*.

%(PSD)s

*Fc*: integer
The center frequency of *x* (defaults to 0), which offsets
the y extents of the plot to reflect the frequency range used
when a signal is acquired and then filtered and downsampled to
baseband.

*cmap*:
A :class:`matplotlib.cm.Colormap` instance; if *None* use
default determined by rc

*xextent*:
The image extent along the x-axis. xextent = (xmin,xmax)
The default is (0,max(bins)), where bins is the return
value from :func:`mlab.specgram`

*minfreq, maxfreq*
Limits y-axis. Both required

*kwargs*:

Additional kwargs are passed on to imshow which makes the
specgram image

Return value is (*Pxx*, *freqs*, *bins*, *im*):

- *bins* are the time points the spectrogram is calculated over
- *freqs* is an array of frequencies
- *Pxx* is a len(times) x len(freqs) array of power
- *im* is a :class:`matplotlib.image.AxesImage` instance

Note: If *x* is real (i.e. non-complex), only the positive
spectrum is shown. If *x* is complex, both positive and
negative parts of the spectrum are shown. This can be
overridden using the *sides* keyword argument.

**Example:**

.. plot:: mpl_examples/pylab_examples/specgram_demo.py

"""

#####################################
# modified axes.specgram() to limit
# the frequencies plotted
#####################################

# this will fail if there isn't a current axis in the global scope
ax = gca()
Pxx, freqs, bins = mlab.specgram(x, NFFT, Fs, detrend,
window, noverlap, pad_to, sides, scale_by_freq)

# modified here
#####################################
if minfreq is not None and maxfreq is not None:
Pxx = Pxx[(freqs >= minfreq) & (freqs <= maxfreq)]
freqs = freqs[(freqs >= minfreq) & (freqs <= maxfreq)]
#####################################

Z = 10. * np.log10(Pxx)
Z = np.flipud(Z)

if xextent is None: xextent = 0, np.amax(bins)
xmin, xmax = xextent
freqs += Fc
extent = xmin, xmax, freqs[0], freqs[-1]
im = ax.imshow(Z, cmap, extent=extent, **kwargs)
ax.axis('auto')

return Pxx, freqs, bins, im

# plot
ax1 = subplot(211)
plot(t, x)
subplot(212, sharex=ax1)

# the minfreq and maxfreq args will limit the frequencies
Pxx, freqs, bins, im = my_specgram(x, NFFT=NFFT, Fs=Fs, noverlap=900,
cmap=cm.Accent, minfreq = 180, maxfreq = 220)
show()
close()

关于python - 在 specgram matplotlib 中切割未使用的频率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19468923/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com