如何使用Butterworth过滤器修复“选定轴超出范围”错误QComboBox

2024-06-16 11:53:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在准备一个包含02个小部件的代码,左边的第一个小部件用于绘制信号、其FFT和log10。右边的第二个是处理和绘制滤波后的信号及其FFT,log10。 我应用了一个组合框来选择巴特沃斯高通和低通

但是,当我在组合框中选择一个选项时,出现了一个错误,即

ValueError: selected axis is out of range

如何修复此代码

我的代码在下面

代码和GUI的链接:https://drive.google.com/drive/folders/1eC15rh-1MLgNl948IpsUjZ773mMhTHlp?usp=sharing

import os, sys, math, pdb

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import QColor, QIcon
from PyQt5.QtWidgets import QMainWindow, QApplication, QFileDialog, QMessageBox, QWidget
from PyQt5.uic import loadUi

from matplotlib.backends.backend_qt5agg import (NavigationToolbar2QT as NavigationToolbar)
from matplotlib.backends.backend_qt5agg import FigureCanvas
from matplotlib.figure import Figure

import numpy as np
from numpy import *

from scipy import signal

from gui3 import Ui_MainWindow



b_Canvas = b_Canvas2 = False
s = 0

class MyMainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MyMainWindow, self).__init__(parent)
        QMainWindow.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        
        self.ui.Show_Signals.clicked.connect(self.show_plot)
        self.ui.cbfilter.currentIndexChanged.connect(self.show_filtering)


    def rm_mpl(self):
        global b_Canvas
        self.ui.verticalLayout.removeWidget(self.canvas)
        self.canvas.close()
        self.ui.verticalLayout.removeWidget(self.toolbar)
        self.toolbar.close()
        b_Canvas = False


    def rm_mpl2(self):
        global b_Canvas2
        self.ui.verticalLayout_2.removeWidget(self.canvas2)
        self.canvas2.close()
        self.ui.verticalLayout_2.removeWidget(self.toolbar2)
        self.toolbar2.close()
        b_Canvas2 = False

    def show_plot(self):
        global b_Canvas, b_Canvas2, s
        
        if b_Canvas == True:
            self.rm_mpl()
        if b_Canvas2 == True:
            self.rm_mpl2()
        
        t_start = float(self.ui.le_time_start.text())
        t_end = float(self.ui.le_time_end.text())
        t_step = float(self.ui.le_time_step.text())
        freq = float(self.ui.le_frequency.text())
        amp = float(self.ui.le_amplitude.text())
        phase = float(self.ui.le_phase.text())
        poly = self.ui.le_poly.text()

        if self.ui.rb_sin.isChecked() == True:
            t = linspace(t_start, t_end, t_step)
            s = amp * np.sin(2 * np.pi * freq * t + phase)
      
        elif self.ui.rb_square.isChecked() == True:
            t = linspace(t_start, t_end, t_step, endpoint=False)
            s = amp * signal.square(2 * np.pi * freq * t)

        elif self.ui.rb_poly.isChecked() == True:
            ps = [float(i) for i in poly.split(',')]
            p = np.poly1d(ps)
            t = linspace(t_start, t_end, t_step)
            s = amp * signal.sweep_poly(t, p)

        elif self.ui.rb_sawtooth.isChecked() == True:
            t = linspace(t_start, t_end, t_step)
            s = amp * signal.sawtooth(2 * np.pi * freq * t)

        if self.ui.rbNoise.isChecked():
            s = s + np.random.randn(len(s)) * 0.1

        fig = Figure()
        self.canvas = FigureCanvas(fig)
        self.ui.verticalLayout.addWidget(self.canvas)

        fig.subplots_adjust(hspace = 1.0)


        wc = float(self.ui.le_CutOff.text())
        N = int(self.ui.le_FFTLength.text())
        M = int(self.ui.le_SignalRange.text())
        wc = wc * pi

        w, Hh = signal.freqz(s, 1, whole=True, worN=N)  # to get entire frequency domain
        wx = fft.fftfreq(len(w)) # to shift to center


        
        # Input signal
        ax1f1 = fig.add_subplot(311)
        ax1f1.plot(s)
        ax1f1.set_title('Input Signal')

        
        # FFT Abs   
        ax1f2 = fig.add_subplot(312)
        ax1f2.plot(w-pi, abs(fft.fftshift(Hh)))
        ax1f2.set_title('Absolute FFT Graph')
        ax1f2.set_xlabel(r"$\omega$", fontsize=14)
        ax1f2.set_ylabel(r"$|H(\omega)| $", fontsize=14)
        ax1f2.axis(xmin=-pi/2, xmax=pi/2)
        
        # FFT Log 
        ax1f3 = fig.add_subplot(313)
        ax1f3.plot(w-pi, 20*log10(abs(fft.fftshift(Hh))))
        ax1f3.set_title('Log Absolute FFT Graph')
        ax1f3.set_xlabel(r"$\omega$", fontsize=14)
        ax1f3.set_ylabel(r"$20\log_{10}|H(\omega)| $", fontsize=14)
        ax1f3.axis(ymin=-40, xmin=-pi/2, xmax=pi/2)
        

        self.canvas.draw()
        
        self.toolbar = NavigationToolbar(self.canvas, self.ui.mplwindow, coordinates=True)
        self.ui.verticalLayout.addWidget(self.toolbar)
        
        b_Canvas = True
        
    def show_filtering(self):
        global b_Canvas, b_Canvas2
        global filtered, s, pass_band, stop_band
        
        if b_Canvas == True:
            self.rm_mpl()
        if b_Canvas2 == True:
            self.rm_mpl2()
        
        strcb = self.ui.cbfilter.currentText()
        if strcb == 'Butterworth Highpass':
            self.butterworth_filter('hp')
        if strcb == 'Butterworth Lowpass':
            self.butterworth_filter('lp')
            
        fig1 = Figure()
        self.canvas = FigureCanvas(fig1)
        self.ui.verticalLayout_2.addWidget(self.canvas)

        fig1.subplots_adjust(hspace = 1.0)

        wc = float(self.ui.le_CutOff.text())
        N = int(self.ui.le_FFTLength.text())
        M = int(self.ui.le_SignalRange.text())
        wc = wc * pi

        w1, Hh1 = signal.freqz(filtered, 1, whole=True, worN=N)  # to get entire frequency domain
        wx1 = fft.fftfreq(len(w1)) # to shift to center
        
        # Filter signal
        ax1f1 = fig1.add_subplot(311)
        ax1f1.plot(filtered)
        ax1f1.set_title('Input Signal')

        
        # FFT Abs Filter   
        ax1f2 = fig1.add_subplot(312)
        ax1f2.plot(w1-pi, abs(fft.fftshift(Hh1)))
        ax1f2.set_title('Absolute FFT Graph')
        ax1f2.set_xlabel(r"$\omega$", fontsize=14)
        ax1f2.set_ylabel(r"$|H(\omega)| $", fontsize=14)
        ax1f2.axis(xmin=-pi/2, xmax=pi/2)
        
        # FFT Log Filter
        ax1f3 = fig1.add_subplot(313)
        ax1f3.plot(w1-pi, 20*log10(abs(fft.fftshift(Hh1))))
        ax1f3.set_title('Log Absolute FFT Graph')
        ax1f3.set_xlabel(r"$\omega$", fontsize=14)
        ax1f3.set_ylabel(r"$20\log_{10}|H(\omega)| $", fontsize=14)
        ax1f3.axis(ymin=-40, xmin=-pi/2, xmax=pi/2)
        

        self.canvas.draw()
        
        self.toolbar = NavigationToolbar(self.canvas, self.ui.mplwindow2, coordinates=True)
        self.ui.verticalLayout_2.addWidget(self.toolbar)
        
        b_Canvas2 = True

    def butterworth_filter(self,param):
        #extract line edit
        global filtered, s, pass_band, stop_band
        pass_band = float(self.ui.pb.text())
        stop_band = float(self.ui.sb.text())
        #filtering
        sos = signal.butter(stop_band,pass_band,param,fs=1000,output='sos')
        filtered = signal.sosfilt(sos,s)
        

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    window = MyMainWindow()
    window.show()
    sys.exit(app.exec_())

enter image description here


Tags: textfromimportselffftletrueui