Skip to content

Commit 530d689

Browse files
committed
update sisotool to use ax for bode_plot
1 parent aef709c commit 530d689

3 files changed

Lines changed: 21 additions & 40 deletions

File tree

control/freqplot.py

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@
118118

119119
def bode_plot(
120120
data, omega=None, *fmt, ax=None, omega_limits=None, omega_num=None,
121-
plot=None, margins=None, method='best', **kwargs):
121+
plot=None, margins=None, margin_info=False, method='best', **kwargs):
122122
"""Bode plot for a system.
123123
124124
Bode plot of a frequency response over a (optional) frequency range.
@@ -139,7 +139,9 @@ def bode_plot(
139139
If True, plot phase in degrees (else radians). Default value (True)
140140
set by config.defaults['freqplot.deg'].
141141
margins : bool
142-
If True, plot gain and phase margin.
142+
If True, plot gain and phase margin. (TODO: merge with margin_info)
143+
margin_info : bool
144+
If True, plot information about gain and phase margin.
143145
method : str, optional
144146
Method to use in computing margins (see :func:`stability_margins`).
145147
*fmt : :func:`matplotlib.pyplot.plot` format string, optional
@@ -410,9 +412,9 @@ def bode_plot(
410412

411413
# Decide on the number of inputs and outputs
412414
ninputs, noutputs = 0, 0
413-
for response in data:
414-
ninputs += response.ninputs
415-
noutputs += response.noutputs
415+
for response in data: # TODO: make more pythonic/numpic
416+
ninputs = max(ninputs, response.ninputs)
417+
noutputs = max(noutputs, response.noutputs)
416418
ntraces = 1 # TODO: assume 1 trace per response for now
417419

418420
# Figure how how many rows and columns to use + offsets for inputs/outputs
@@ -426,21 +428,21 @@ def bode_plot(
426428
if len(ax) == nrows * ncols:
427429
# Assume that the shape is right (no easy way to infer this)
428430
ax = np.array(ax).reshape(nrows, ncols)
429-
elif len(ax) != 0 and 'sisotool' not in kwargs: # TODO: remove sisotool
431+
elif len(ax) != 0:
430432
# Need to generate a new figure
431433
fig, ax = plt.figure(), None
432434
else:
433435
# Blank figure, just need to recreate axes
434436
ax = None
435437

436438
# Create new axes, if needed, and customize them
437-
if ax is None and 'sisotool' not in kwargs: # TODO: remove sisotool
439+
if ax is None:
438440
with plt.rc_context(_freqplot_rcParams):
439441
ax_array = fig.subplots(nrows, ncols, sharex=True, squeeze=False)
440442
fig.set_tight_layout(True)
441443
fig.align_labels()
442444

443-
elif 'sisotool' not in kwargs: # TODO: remove sisotool
445+
else:
444446
# Make sure the axes are the right shape
445447
if ax.shape != (nrows, ncols):
446448
raise ValueError(
@@ -457,31 +459,8 @@ def bode_plot(
457459
# TODO: rewrite this code to us subplot and the ax keyword to implement
458460
# the same functionality.
459461

460-
# Get the current figure
461-
if 'sisotool' in kwargs:
462-
fig = kwargs.pop('fig') # redo to use ax parameter
463-
ax_mag = fig.axes[0]
464-
ax_phase = fig.axes[2]
465-
sisotool = kwargs.pop('sisotool')
466-
else:
467-
fig = plt.gcf()
468-
ax_mag = None
469-
ax_phase = None
470-
sisotool = False
471-
472-
# Get the current axes if they already exist
473-
for ax in fig.axes:
474-
if ax.get_label() == 'control-bode-magnitude':
475-
ax_mag = ax
476-
elif ax.get_label() == 'control-bode-phase':
477-
ax_phase = ax
478-
479-
# If no axes present, create them from scratch
480-
if ax_mag is None or ax_phase is None:
481-
plt.clf()
482-
ax_mag = plt.subplot(211, label='control-bode-magnitude')
483-
ax_phase = plt.subplot(
484-
212, label='control-bode-phase', sharex=ax_mag)
462+
ax_mag = ax_array[0, 0]
463+
ax_phase = ax_array[1, 0]
485464

486465
#
487466
# Plot the data
@@ -633,7 +612,7 @@ def bode_plot(
633612
ax_mag.set_ylim(mag_ylim)
634613
ax_phase.set_ylim(phase_ylim)
635614

636-
if sisotool:
615+
if margin_info:
637616
ax_mag.text(
638617
0.04, 0.06,
639618
'G.M.: %.2f %s\nFreq: %.2f %s' %

control/sisotool.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ def sisotool(sys, initial_gain=None, xlim_rlocus=None, ylim_rlocus=None,
100100
plt.close(fig)
101101
fig,axes = plt.subplots(2, 2)
102102
fig.canvas.manager.set_window_title('Sisotool')
103+
else:
104+
axes = np.array(fig.get_axes()).reshape(2, 2)
103105

104106
# Extract bode plot parameters
105107
bode_plot_params = {
@@ -109,9 +111,9 @@ def sisotool(sys, initial_gain=None, xlim_rlocus=None, ylim_rlocus=None,
109111
'deg': deg,
110112
'omega_limits': omega_limits,
111113
'omega_num' : omega_num,
112-
'sisotool': True,
113-
'fig': fig,
114-
'margins': margins_bode
114+
'ax': axes[:, 0:1],
115+
'margins': margins_bode,
116+
'margin_info': True,
115117
}
116118

117119
# Check to see if legacy 'PrintGain' keyword was used

control/tests/sisotool_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ def test_sisotool(self, tsys):
7878
'deg': True,
7979
'omega_limits': None,
8080
'omega_num': None,
81-
'sisotool': True,
82-
'fig': fig,
83-
'margins': True
81+
'ax': np.array([[ax_mag], [ax_phase]]),
82+
'margins': True,
83+
'margin_info': True,
8484
}
8585

8686
# Check that the xaxes of the bode plot are shared before the rlocus click

0 commit comments

Comments
 (0)