Skip to content

Commit 06e5c34

Browse files
committed
Always return phase in radians in bode_plot
Previously, bode_plot returned phase and magnitude in different units (dB/absolute magnitude, radians/degrees) depending on the values of boolean flags. This was inconsistent with the documentation and the tests. This is now made consistent, so that bode_plot always returns absolute magnitude and phase in radians, and the documentation is consistent with the behavior.
1 parent ebf8364 commit 06e5c34

2 files changed

Lines changed: 12 additions & 9 deletions

File tree

control/freqplot.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def bode_plot(syslist, omega=None, dB=None, Hz=None, deg=None,
7777
Hz : boolean
7878
If True, plot frequency in Hz (omega must be provided in rad/sec)
7979
deg : boolean
80-
If True, return phase in degrees (else radians)
80+
If True, plot phase in degrees (else radians)
8181
Plot : boolean
8282
If True, plot magnitude and phase
8383
*args, **kwargs:
@@ -88,9 +88,9 @@ def bode_plot(syslist, omega=None, dB=None, Hz=None, deg=None,
8888
mag : array (list if len(syslist) > 1)
8989
magnitude
9090
phase : array (list if len(syslist) > 1)
91-
phase
91+
phase in radians
9292
omega : array (list if len(syslist) > 1)
93-
frequency
93+
frequency in rad/sec
9494
9595
Notes
9696
-----
@@ -129,16 +129,15 @@ def bode_plot(syslist, omega=None, dB=None, Hz=None, deg=None,
129129
omega = default_frequency_range(syslist)
130130

131131
# Get the magnitude and phase of the system
132+
omega = np.array(omega)
132133
mag_tmp, phase_tmp, omega_sys = sys.freqresp(omega)
133134
mag = np.atleast_1d(np.squeeze(mag_tmp))
134135
phase = np.atleast_1d(np.squeeze(phase_tmp))
135136
phase = unwrap(phase)
136137
if Hz:
137-
omega_plot = omega_sys/(2*sp.pi)
138+
omega_plot = omega_sys / (2 * np.pi)
138139
else:
139140
omega_plot = omega_sys
140-
if dB: mag = 20*sp.log10(mag)
141-
if deg: phase = phase * 180 / sp.pi
142141

143142
mags.append(mag)
144143
phases.append(phase)
@@ -150,7 +149,7 @@ def bode_plot(syslist, omega=None, dB=None, Hz=None, deg=None,
150149
# Magnitude plot
151150
plt.subplot(211);
152151
if dB:
153-
plt.semilogx(omega_plot, mag, *args, **kwargs)
152+
plt.semilogx(omega_plot, 20 * np.log10(mag), *args, **kwargs)
154153
else:
155154
plt.loglog(omega_plot, mag, *args, **kwargs)
156155
plt.hold(True);
@@ -162,7 +161,11 @@ def bode_plot(syslist, omega=None, dB=None, Hz=None, deg=None,
162161

163162
# Phase plot
164163
plt.subplot(212);
165-
plt.semilogx(omega_plot, phase, *args, **kwargs)
164+
if deg:
165+
phase_plot = phase * 180 / np.pi
166+
else:
167+
phase_plot = phase
168+
plt.semilogx(omega_plot, phase_plot, *args, **kwargs)
166169
plt.hold(True);
167170

168171
# Add a grid to the plot + labeling

control/tests/discrete_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ def test_discrete_bode(self):
314314
H_z = list(map(lambda w: 1./(np.exp(1.j * w) + 0.5), omega))
315315
np.testing.assert_array_almost_equal(omega, omega_out)
316316
np.testing.assert_array_almost_equal(mag_out, np.absolute(H_z))
317-
np.testing.assert_array_almost_equal(mag_out, np.absolute(H_z))
317+
np.testing.assert_array_almost_equal(phase_out, np.angle(H_z))
318318

319319
def suite():
320320
return unittest.TestLoader().loadTestsFromTestCase(TestDiscrete)

0 commit comments

Comments
 (0)