Friday, November 13, 2020

Signal Processing with Python GUI: Part 2

This Content is supported by BALIGE PUBLISHINGVisit this link

Tutorial Steps To Create GUI For FFT With Some Other Input Signals. See Part 1.

Add another Radio Button widget on the form. Set its text property to Sawtooth and its objectName to rbSawtooth as shown in figure below.



Modify main_fft.py as follows:

#main_fft.py

from PyQt5.QtWidgets import *
from PyQt5.uic import loadUi
from matplotlib.backends.backend_qt5agg import (NavigationToolbar2QT as NavigationToolbar)

import numpy as np
from scipy import signal
from numpy import *
import matplotlib as mpl
from scipy.signal import chirp

class DemoGUIFFT(QMainWindow):   
    def __init__(self):
        
        QMainWindow.__init__(self)
        loadUi("gui_fft.ui",self)

        self.setWindowTitle("GUI Demo for FFT")
        self.pbShow.clicked.connect(self.show_graph)
        self.addToolBar(NavigationToolbar(self.widgetSignal.canvas, self))        
        self.rbChirp.toggled.connect(self.show_chirp)
        self.rbSawtooth.toggled.connect(self.show_sawtooth)


    def show_graph(self):
        wc = float(self.leCutOff.text())
        N = int(self.leFFTLength.text())
        M = int(self.leSignalRange.text())
        wc = wc*pi
        
        # widgetSignal
        n = arange(-M, M)
        h = wc/pi * sinc(wc*(n)/pi)
        mpl.style.use('seaborn')
        self.widgetSignal.canvas.axis1.clear()       
        self.widgetSignal.canvas.axis1.stem(n,h,\
            basefmt='r-',use_line_collection=True)
        self.widgetSignal.canvas.axis1.annotate('$n$', xy=(0.98, 0), \
            ha='left', va='top', xycoords='axes fraction', \
            fontsize=20)
        self.widgetSignal.canvas.axis1.annotate('$h$', xy=(0, 1), \
            xytext=(-15,5), ha='left', va='top', \
            xycoords='axes fraction', textcoords='offset points', \
            fontsize=20)
        self.widgetSignal.canvas.axis1.set_title('Stem Graph')
        self.widgetSignal.canvas.axis1.set_facecolor('lightblue')
        self.widgetSignal.canvas.axis1.grid()
        self.widgetSignal.canvas.draw()
        self.show_fft(h)

    def show_fft(self, h):
        wc = float(self.leCutOff.text())
        N = int(self.leFFTLength.text())
        M = int(self.leSignalRange.text())
        wc = wc*pi
        
        # widgetFFTAbs
        # get entire frequency domain
        w,Hh = signal.freqz(h,1,whole=True, worN=N)        
        wx = fft.fftfreq(len(w))    # shift to center for plotting
        
        self.widgetFFTAbs.canvas.axis1.clear()
        self.widgetFFTAbs.canvas.axis1.plot(w-pi,\
            abs(fft.fftshift(Hh)), color='red', linewidth=3.0)
        self.widgetFFTAbs.canvas.axis1.axis(xmax=pi/2,xmin=-pi/2)
        self.widgetFFTAbs.canvas.axis1.vlines([-1.1,1.1],\
            0,1.2,color='g',lw=2.,linestyle='--',)
        self.widgetFFTAbs.canvas.axis1.hlines(1,\
            -pi,pi,color='g',lw=2.,linestyle='--',)
        self.widgetFFTAbs.canvas.axis1.annotate(r'$\omega$',\
            xy=(0.98, 0), ha='left', va='top', \
            xycoords='axes fraction', fontsize=22)       
        self.widgetFFTAbs.canvas.axis1.set_ylabel(r"$|H(\omega)| $",\
            fontsize=22)
        self.widgetFFTAbs.canvas.axis1.set_title('Absolute FFT Graph')
        self.widgetFFTAbs.canvas.axis1.set_facecolor('lightblue')
        self.widgetFFTAbs.canvas.axis1.grid()
        self.widgetFFTAbs.canvas.draw()        

        # widgetFFTLog
        # get entire frequency domain
        w,Hh = signal.freqz(h,1,whole=True, worN=N) 
        wx = fft.fftfreq(len(w))    # shift to center for plotting
        
        self.widgetFFTLog.canvas.axis1.clear()
        self.widgetFFTLog.canvas.axis1.plot(w-pi,\
            20*log10(abs(fft.fftshift(Hh))),color='red', \
            linewidth=3.0)
        self.widgetFFTLog.canvas.axis1.axis(ymin=-60,\
            xmax=pi/2,xmin=-pi/2)
        self.widgetFFTLog.canvas.axis1.vlines([-wc,wc],10,\
            -40,color='g',lw=2.,linestyle='--',)
        self.widgetFFTLog.canvas.axis1.hlines(0,\
            -pi,pi,color='g',lw=2.,linestyle='--',)
        self.widgetFFTLog.canvas.axis1.annotate(r'$\omega$', \
            xy=(0.98, 0), ha='left', va='top', \
            xycoords='axes fraction', fontsize=22)
        self.widgetFFTLog.canvas.axis1.set_ylabel(\
            r"$20\log_{10}|H(\omega)| $",fontsize=18)
        self.widgetFFTLog.canvas.axis1.set_title('Log Absolute FFT Graph')
        self.widgetFFTLog.canvas.axis1.set_facecolor('lightblue')
        self.widgetFFTLog.canvas.axis1.grid()
        self.widgetFFTLog.canvas.draw()          

    def show_chirp(self):
        x_start = float(self.leXStart.text())
        x_end = float(self.leXEnd.text())
        f_start = float(self.leFStart.text())
        f_end = float(self.leFEnd.text())
        
        # widgetSignal
        t = linspace(x_start, x_end, 5001)
        w = chirp(t, f0=f_start, f1=f_end, t1=10, method='linear')
        
        self.widgetSignal.canvas.axis1.clear()
        #self.widgetSignal.canvas.axis1.plot(t, w)
        self.widgetSignal.canvas.axis1.plot(t,w,linewidth=3.0)
        self.widgetSignal.canvas.axis1.annotate('$sec$', xy=(0.98, 0), \
            ha='left', va='top', xycoords='axes fraction', fontsize=20)
        self.widgetSignal.canvas.axis1.annotate('$h$', xy=(0, 1), \
            xytext=(-15,5), ha='left', va='top', \
            xycoords='axes fraction', textcoords='offset points', \
            fontsize=20)
        self.widgetSignal.canvas.axis1.set_title('Chirp Graph')
        self.widgetSignal.canvas.axis1.set_facecolor('lightblue')
        self.widgetSignal.canvas.axis1.grid()
        self.widgetSignal.canvas.draw()
        
        self.show_fft(w)
      
    def show_sawtooth(self):
        x_start = float(self.leXStart.text())
        x_end = float(self.leXEnd.text())
       
        # widgetSignal
        t = linspace(x_start, x_end, 5001)
        w = signal.sawtooth(2 * np.pi * 5 * t)
        self.widgetSignal.canvas.axis1.clear()
        self.widgetSignal.canvas.axis1.plot(t, w,linewidth=3.0)
        self.widgetSignal.canvas.axis1.annotate('$sec$', xy=(0.98, 0), \
            ha='left', va='top', xycoords='axes fraction', \
            fontsize=20)
        self.widgetSignal.canvas.axis1.annotate('$h$', xy=(0, 1), \
            xytext=(-15,5), ha='left', va='top', \
            xycoords='axes fraction', textcoords='offset points', \
            fontsize=20)
        self.widgetSignal.canvas.axis1.set_title('Chirp Graph')
        self.widgetSignal.canvas.axis1.set_title('Sawtooth Graph')
        self.widgetSignal.canvas.axis1.set_facecolor('khaki')
        self.widgetSignal.canvas.axis1.grid()
        self.widgetSignal.canvas.draw()
        
        self.show_fft(w)
       
if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    ex = DemoGUIFFT()
    ex.show()
    sys.exit(app.exec_())

Run the program and click on the radio button to see chirp signal and its Fourier transform as shown in figure below.


Add another Radio Button widget on the form. Set its text property to Sawtooth and its objectName to rbSawtooth as shown figure below.


Modify main_fft.py by adding code in line 23 and 35-57 as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#main_fft.py

from PyQt5.QtWidgets import *
from PyQt5.uic import loadUi
from matplotlib.backends.backend_qt5agg import (NavigationToolbar2QT as NavigationToolbar)

import numpy as np
from scipy import signal
from numpy import *
import matplotlib as mpl
from scipy.signal import chirp

class DemoGUIFFT(QMainWindow):   
    def __init__(self):
        
        QMainWindow.__init__(self)
        loadUi("gui_fft.ui",self)

        self.setWindowTitle("GUI Demo for FFT")
        self.pbShow.clicked.connect(self.show_graph)
        self.addToolBar(NavigationToolbar(self.widgetSignal.canvas, self))        
        self.rbChirp.toggled.connect(self.show_chirp)
        self.rbSawtooth.toggled.connect(self.show_sawtooth)


    def show_graph(self):
        ...

    def show_fft(self, h):
        ... 

    def show_chirp(self):
        ...
      
    def show_sawtooth(self):
        x_start = float(self.leXStart.text())
        x_end = float(self.leXEnd.text())
       
        # widgetSignal
        t = linspace(x_start, x_end, 5001)
        w = signal.sawtooth(2 * np.pi * 5 * t)
        self.widgetSignal.canvas.axis1.clear()
        self.widgetSignal.canvas.axis1.plot(t, w,linewidth=3.0)
        self.widgetSignal.canvas.axis1.annotate('$sec$', xy=(0.98, 0), \
            ha='left', va='top', xycoords='axes fraction', \
            fontsize=20)
        self.widgetSignal.canvas.axis1.annotate('$h$', xy=(0, 1), \
            xytext=(-15,5), ha='left', va='top', \
            xycoords='axes fraction', textcoords='offset points', \
            fontsize=20)
        self.widgetSignal.canvas.axis1.set_title('Chirp Graph')
        self.widgetSignal.canvas.axis1.set_title('Sawtooth Graph')
        self.widgetSignal.canvas.axis1.set_facecolor('khaki')
        self.widgetSignal.canvas.axis1.grid()
        self.widgetSignal.canvas.draw()
        
        self.show_fft(w)
       
if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    ex = DemoGUIFFT()
    ex.show()
    sys.exit(app.exec_())

Run the program and click on the radio button to see sawtooth signal and its Fourier transform as shown in figure below.


On gui_fft.ui, add two Radio Button widgets on the form. Set their text properties to Square and Sweep Poly and their objectName properties to rbSquare and rbSweepPoly as shown in figure blow.


Modify main_fft.py by adding code in line 23-24 and 35-82 as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#main_fft.py

from PyQt5.QtWidgets import *
from PyQt5.uic import loadUi
from matplotlib.backends.backend_qt5agg import (NavigationToolbar2QT as NavigationToolbar)

import numpy as np
from scipy import signal
from numpy import *
import matplotlib as mpl
from scipy.signal import chirp

class DemoGUIFFT(QMainWindow):   
    def __init__(self):
        
        QMainWindow.__init__(self)
        loadUi("gui_fft.ui",self)

        self.setWindowTitle("GUI Demo for FFT")
        self.pbShow.clicked.connect(self.show_graph)
        self.addToolBar(NavigationToolbar(self.widgetSignal.canvas, self))        
        self.rbChirp.toggled.connect(self.show_chirp)
        self.rbSquare.toggled.connect(self.show_square)
        self.rbSweepPoly.toggled.connect(self.show_sweep_poly)

    def show_graph(self):
        ...

    def show_fft(self, h):
        ...

    def show_chirp(self):
        ...
 
    def show_square(self):
        x_start = float(self.leXStart.text())
        x_end = float(self.leXEnd.text())
        
        # widgetSignal
        t = linspace(x_start, x_end, 500, endpoint=False)
        w = signal.square(2 * pi * 2 * t)
        self.widgetSignal.canvas.axis1.clear()
        self.widgetSignal.canvas.axis1.plot(t, w, linewidth=3.0)
        self.widgetSignal.canvas.axis1.annotate('$sec$', xy=(0.98, 0), \
            ha='left', va='top', xycoords='axes fraction', \
            fontsize=20)
        self.widgetSignal.canvas.axis1.annotate('$h$', xy=(0, 1), \
            xytext=(-15,5), ha='left', va='top', \
            xycoords='axes fraction', textcoords='offset points', \
            fontsize=20)
        self.widgetSignal.canvas.axis1.set_title('Square Graph')
        self.widgetSignal.canvas.axis1.set_facecolor('lightblue')
        self.widgetSignal.canvas.axis1.grid()
        self.widgetSignal.canvas.draw()
        
        self.show_fft(w)

    def show_sweep_poly(self):
        global y
        x_start = float(self.leXStart.text())
        x_end = float(self.leXEnd.text())
      
        # widgetSignal
        p = np.poly1d([0.025, -0.36, 1.25, 2.0])
        t = np.linspace(x_start, x_end, 5001)
        y = signal.sweep_poly(t, p)   
            
        self.widgetSignal.canvas.axis1.clear()
        self.widgetSignal.canvas.axis1.plot(t, y, linewidth=3.0)
        self.widgetSignal.canvas.axis1.annotate('$sec$', xy=(0.98, 0), \
            ha='left', va='top', xycoords='axes fraction', \
            fontsize=20)
        self.widgetSignal.canvas.axis1.annotate('$h$', xy=(0, 1), \
            xytext=(-15,5), ha='left', va='top', \
            xycoords='axes fraction', textcoords='offset points', \
            fontsize=20)
        self.widgetSignal.canvas.axis1.set_title('Sweep Poly Graph')
        self.widgetSignal.canvas.axis1.set_facecolor('lightblue')
        self.widgetSignal.canvas.axis1.grid()
        self.widgetSignal.canvas.draw()
        
        self.show_fft(y)
            
if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    ex = DemoGUIFFT()
    ex.show()
    sys.exit(app.exec_())

Run the program and click on the rbSquare widget to see square signal and its Fourier transform as shown in figure below.


Run the program and click on the rbSweepPoly widget to see sweep poly signal and its Fourier transform as shown in figure below.







No comments:

Post a Comment