-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathfreqz_plot.py
72 lines (61 loc) · 2.11 KB
/
freqz_plot.py
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
# -*- coding: utf-8 -*-
"""
Created on Thu Mar 30 22:24:46 2017
@author: Robert
Modified: Gerald Schuller, Apr. 2017
"""
import scipy.signal as sig
import numpy as np
import matplotlib.pyplot as plt
def freqz_plot(x, behaviour='matlab', color='b'):
""" Plots the frequency response like freqz would do in Matlab/Octave would do
Args:
x (np.array) input signal
behaviour (str) defines wether to behave like 'matlab'
(default) or 'octave' freqz plots
color (char) default 'b' -> blue
"""
# get frequency bins and according magnitude values
f, h = sig.freqz(x)
# normalized frequency
fNorm = f/np.pi
# magnitude in dB
hdB = 20 * np.log10(abs(h)+1e-5) #"+1e-5" avoids log10(0)!
# open figure
plt.figure()
# octave also plots an extra zoomed version for the pass band
if behaviour == 'octave':
# Passband
plt.subplot(311)
plt.title('Passband')
plt.plot(f, hdB, color)
plt.axis([0,3.14,np.max(hdB)-6,np.max(hdB)+1])
plt.grid(True)
plt.xlabel('Normalized Frequency (rad/sample)')
plt.ylabel('Magnitude (dB)')
# Magnitude/Stopband
if behaviour == 'octave':
plt.subplot(312)
plt.title('Stopband')
else:
plt.subplot(211)
#plt.title('Magnitude')
plt.plot(f, hdB, color)
plt.axis([0,3.14,np.min(hdB)-1,np.max(hdB)+1])
plt.grid(True)
#plt.xlabel('Normalized Frequency (rad/sample)')
plt.ylabel('Magnitude (dB)')
# Phase
if behaviour == 'octave':
plt.subplot(313)
else:
plt.subplot(212)
#plt.title('Phase')
angles = np.angle(h)
#angles = np.unwrap(np.angle(h)) #unwrapped version
anglesGrad = (360 * angles)/(2*np.pi)
plt.plot(f, anglesGrad, color)
plt.axis([0,3.14,np.min(anglesGrad),np.max(anglesGrad)])
plt.grid(True)
plt.xlabel('Normalized Frequency (rad/sample)')
plt.ylabel('Phase (degrees)')