【问题标题】:How can I plot a spectrogram of a signal by computing the power spectrum on binned windows?如何通过计算分箱窗口上的功率谱来绘制信号的频谱图?
【发布时间】:2016-03-27 07:44:01
【问题描述】:

在这里我可以产生一个信号:

import numpy as np
from matplotlib import pyplot as plt
from numpy.lib import stride_tricks
import seaborn as sns
sns.set(style = "darkgrid" )

fs = 48000.0
t = np.arange(0, 10, 1.0/fs) # 0 to 10 sec at 48k samples per second
f0 = 1000
phi = np.pi/2  # pi/2

x = 0 # initial x
f = [500, 100, 40, 1] #vector of frequencies
A = [1, 0.5, 0.25, 0.1] #vector of amplitudes
for i in range(0, len(f)):
    x = x +  A[i] * np.sin(2 * np.pi * f[i] * t + phi) #add waves
x = x + max(x) # shift plot upwards
plt.plot(t, x)
plt.axis([0, .05, 0, max(x)])
plt.xlabel('time')
plt.ylabel('amplitude')
plt.show()

在这里我可以绘制整个信号的功率谱:

time_step = 1/fs
ps = np.abs(np.fft.fft(x))**2
freqs = np.fft.fftfreq(x.size, time_step)
idx = np.argsort(freqs)
plt.plot(freqs[idx], 256*ps[idx]/max(ps[idx])) # set max to 256 for later image plotting purposes
plt.xlabel('frequency')
plt.ylabel('power')
plt.show()

接下来我想生成一个频谱图,表示为频率(y 轴)和时间(x 轴)的图像,但我是傅立叶分析的新手,对如何使用 window function(矩形,汉明,汉宁等)在这个阶段。有没有合适的方法来做到这一点,以便可以使用我选择的窗口函数来及时分解信号?

【问题讨论】:

    标签: python fft


    【解决方案1】:

    添加这个:

    M = 5000
    overlap = 500
    unique = M - overlap
    han = np.hanning(M)
    f_border = 2*max(f)
    
    for i in range(0, x.shape[0], unique):
        if i + M > x.shape[0]:
            break
        curr_x = x[i:i+M]
        y = 10*np.log10(np.abs(np.fft.fft(curr_x*han))**2)
        if i == 0:
            freqs = np.fft.fftfreq(curr_x.size, time_step)
            idx = np.argsort(freqs)
            freqs = freqs[idx]
            idx2 = np.where(np.logical_and(freqs > 0, freqs < f_border))[0]
        y = y[idx][idx2][np.newaxis].T
        try:
            stereogram = np.hstack([stereogram, y])
        except NameError:
            stereogram = y
    
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.imshow(stereogram)
    yticks = ax.get_yticks()[1:-1]
    plt.yticks(yticks, (yticks * f_border/yticks[-1]).astype('str'))
    plt.ylabel('frequency')
    plt.xlabel('time')
    plt.show()
    

    【讨论】:

      【解决方案2】:

      或者您可以使用matplotlib.pyplot.specgram 参见:http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.specgram

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-07-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-09
        • 2021-05-15
        相关资源
        最近更新 更多