Skip to content

Commit eabe562

Browse files
committed
Update bode_plot and gangof4_plot axes label handling
Changed the labels for subplots to be of the form `control-plotname-subfigname` for consistency. Moved around some of the code from @roryyorke to put it in a single place. Added documentation.
1 parent dc1820a commit eabe562

2 files changed

Lines changed: 46 additions & 27 deletions

File tree

control/freqplot.py

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -135,20 +135,6 @@ def bode_plot(syslist, omega=None, dB=None, Hz=None, deg=None,
135135
else:
136136
omega = sp.logspace(np.log10(omega_limits[0]), np.log10(omega_limits[1]), endpoint=True)
137137

138-
if Plot:
139-
fig = plt.gcf()
140-
ax_mag = None
141-
ax_phase = None
142-
for ax in fig.axes:
143-
if ax.get_label() == 'pycontrol-bode-mag':
144-
ax_mag = ax
145-
elif ax.get_label() == 'pycontrol-bode-phs':
146-
ax_phase = ax
147-
if ax_mag is None or ax_phase is None:
148-
plt.clf()
149-
ax_mag = plt.subplot(211, label = 'pycontrol-bode-mag')
150-
ax_phase = plt.subplot(212, label = 'pycontrol-bode-phs', sharex=ax_mag)
151-
152138
mags, phases, omegas, nyquistfrqs = [], [], [], []
153139
for sys in syslist:
154140
if (sys.inputs > 1 or sys.outputs > 1):
@@ -185,10 +171,30 @@ def bode_plot(syslist, omega=None, dB=None, Hz=None, deg=None,
185171
#! TODO: Not current implemented; just use subplot for now
186172

187173
if (Plot):
188-
# Create a unique label to fix bug in matplotlib<=2.1
189-
# See https://github.com/matplotlib/matplotlib/issues/9024
190-
import random
191-
figlabel = str(random.randint(1, 1e6))
174+
# Set up the axes with labels so that multiple calls to
175+
# bode_plot will superimpose the data. This was implicit
176+
# before matplotlib 2.1, but changed after that (See
177+
# https://github.com/matplotlib/matplotlib/issues/9024).
178+
# The code below should work on all cases.
179+
180+
# Get the current figure
181+
fig = plt.gcf()
182+
ax_mag = None
183+
ax_phase = None
184+
185+
# Get the current axes if they already exist
186+
for ax in fig.axes:
187+
if ax.get_label() == 'control-bode-magnitude':
188+
ax_mag = ax
189+
elif ax.get_label() == 'control-bode-phase':
190+
ax_phase = ax
191+
192+
# If no axes present, create them from scratch
193+
if ax_mag is None or ax_phase is None:
194+
plt.clf()
195+
ax_mag = plt.subplot(211, label = 'control-bode-magnitude')
196+
ax_phase = plt.subplot(212, label = 'control-bode-phase',
197+
sharex=ax_mag)
192198

193199
# Magnitude plot
194200
if dB:
@@ -372,25 +378,29 @@ def gangof4_plot(P, C, omega=None):
372378
L = P * C;
373379
S = feedback(1, L);
374380
T = L * S;
375-
381+
382+
# Set up the axes with labels so that multiple calls to
383+
# gangof4_plot will superimpose the data. See details in bode_plot.
376384
plot_axes = {'t' : None, 's' : None, 'ps' : None, 'cs' : None}
377385
for ax in plt.gcf().axes:
378386
label = ax.get_label()
379-
if label.startswith('pycontrol-gof-'):
380-
key = label[len('pycontrol-gof-'):]
387+
if label.startswith('control-gangof4-'):
388+
key = label[len('control-gangof4-'):]
381389
if key not in plot_axes:
382-
raise RuntimeError("unknown gof axis type '{}'".format(label))
390+
raise RuntimeError("unknown gangof4 axis type '{}'".format(label))
383391
plot_axes[key] = ax
384392

385-
# if any are missing, start from scratch
393+
# if any of the axes are missing, start from scratch
386394
if any((ax is None for ax in plot_axes.values())):
387395
plt.clf()
388-
plot_axes = {'t' : plt.subplot(221,label='pycontrol-gof-t'),
389-
'ps' : plt.subplot(222,label='pycontrol-gof-ps'),
390-
'cs' : plt.subplot(223,label='pycontrol-gof-cs'),
391-
's' : plt.subplot(224,label='pycontrol-gof-s')}
396+
plot_axes = {'t' : plt.subplot(221,label='control-gangof4-t'),
397+
'ps' : plt.subplot(222,label='control-gangof4-ps'),
398+
'cs' : plt.subplot(223,label='control-gangof4-cs'),
399+
's' : plt.subplot(224,label='control-gangof4-s')}
392400

401+
#
393402
# Plot the four sensitivity functions
403+
#
394404

395405
#! TODO: Need to add in the mag = 1 lines
396406
mag_tmp, phase_tmp, omega = T.freqresp(omega);

doc/control.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ Frequency domain plotting
4444
gangof4_plot
4545
nichols_plot
4646

47+
Note: For plotting commands that create multiple axes on the same plot, the
48+
individual axes can be retrieved using the axes label (retrieved using the
49+
`get_label` method for the matplotliib axes object). The following labels
50+
are currently defined:
51+
52+
* Bode plots: `control-bode-magnitude`, `control-bode-phase`
53+
* Gang of 4 plots: `control-gangof4-s`, `control-gangof4-cs`,
54+
`control-gangof4-ps`, `control-gangof4-t`
55+
4756
Time domain simulation
4857
======================
4958

0 commit comments

Comments
 (0)