使用scipy.signal.spectrogram在pyqtgraph中绘制wav文件的频谱

发布于 2021-01-29 15:03:22

我有一个用于音乐和语音分析的PyQt plus pyqtgraph程序,我想绘制一个wav文件的频谱(使用scipy
python软件包计算)。我可以在matplotlib中做到这一点,但是由于matplotlib的性能,我需要切换到pyqtgraph,但是我找不到任何一致的方法来将scipy.signal.spectrogram的输出绘制到pyqtgraph中

谢谢!

关注者
0
被浏览
269
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    Scipy频谱图的输出可以很容易地从pyqtgraph绘制为ImageItem。通常,所得频谱图仅是灰度的。您可以使用直方图最轻松地进行调整。

    例如,以下是如何使SciPy示例适用于声谱图以使用pyqtgraph(以pyqtgraph中的示例为基础):

    from scipy import signal
    import matplotlib.pyplot as plt
    import numpy as np
    import pyqtgraph
    
    # Create the data
    fs = 10e3
    N = 1e5
    amp = 2 * np.sqrt(2)
    noise_power = 0.01 * fs / 2
    time = np.arange(N) / float(fs)
    mod = 500*np.cos(2*np.pi*0.25*time)
    carrier = amp * np.sin(2*np.pi*3e3*time + mod)
    noise = np.random.normal(scale=np.sqrt(noise_power), size=time.shape)
    noise *= np.exp(-time/5)
    x = carrier + noise
    f, t, Sxx = signal.spectrogram(x, fs)
    
    # Interpret image data as row-major instead of col-major
    pyqtgraph.setConfigOptions(imageAxisOrder='row-major')
    
    pyqtgraph.mkQApp()
    win = pyqtgraph.GraphicsLayoutWidget()
    # A plot area (ViewBox + axes) for displaying the image
    p1 = win.addPlot()
    
    # Item for displaying image data
    img = pyqtgraph.ImageItem()
    p1.addItem(img)
    # Add a histogram with which to control the gradient of the image
    hist = pyqtgraph.HistogramLUTItem()
    # Link the histogram to the image
    hist.setImageItem(img)
    # If you don't add the histogram to the window, it stays invisible, but I find it useful.
    win.addItem(hist)
    # Show the window
    win.show()
    # Fit the min and max levels of the histogram to the data available
    hist.setLevels(np.min(Sxx), np.max(Sxx))
    # This gradient is roughly comparable to the gradient used by Matplotlib
    # You can adjust it and then save it using hist.gradient.saveState()
    hist.gradient.restoreState(
            {'mode': 'rgb',
             'ticks': [(0.5, (0, 182, 188, 255)),
                       (1.0, (246, 111, 0, 255)),
                       (0.0, (75, 0, 113, 255))]})
    # Sxx contains the amplitude for each pixel
    img.setImage(Sxx)
    # Scale the X and Y Axis to time and frequency (standard is pixels)
    img.scale(t[-1]/np.size(Sxx, axis=1),
              f[-1]/np.size(Sxx, axis=0))
    # Limit panning/zooming to the spectrogram
    p1.setLimits(xMin=0, xMax=t[-1], yMin=0, yMax=f[-1])
    # Add labels to the axis
    p1.setLabel('bottom', "Time", units='s')
    # If you include the units, Pyqtgraph automatically scales the axis and adjusts the SI prefix (in this case kHz)
    p1.setLabel('left', "Frequency", units='Hz')
    
    # Plotting with Matplotlib in comparison
    plt.pcolormesh(t, f, Sxx)
    plt.ylabel('Frequency [Hz]')
    plt.xlabel('Time [sec]')
    plt.colorbar()
    plt.show()
    
    pyqtgraph.Qt.QtGui.QApplication.instance().exec_()
    

    Matpotlib频谱图

    Pyqtgraph ImageItem



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看