Skip to content

Commit bdf81b1

Browse files
make it so rlocus does not always create a new figure, so it is like matlab and control.sisotool (#413)
* rlocus changed to use current plotting axis rather than always creating a new figure, with an option to specify a desired matplotlib axis instead * rlocus: add title to root locus plot axes rather than renaming figure window
1 parent 6e7480e commit bdf81b1

File tree

2 files changed

+24
-30
lines changed

2 files changed

+24
-30
lines changed

control/rlocus.py

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,10 @@
4848
# Packages used by this module
4949
from functools import partial
5050
import numpy as np
51-
import matplotlib
51+
import matplotlib as mpl
5252
import matplotlib.pyplot as plt
5353
from numpy import array, poly1d, row_stack, zeros_like, real, imag
5454
import scipy.signal # signal processing toolbox
55-
import pylab # plotting routines
5655
from .xferfcn import _convert_to_transfer_function
5756
from .exception import ControlMIMONotImplemented
5857
from .sisotool import _SisotoolUpdate
@@ -63,15 +62,16 @@
6362
# Default values for module parameters
6463
_rlocus_defaults = {
6564
'rlocus.grid': True,
66-
'rlocus.plotstr': 'b' if int(matplotlib.__version__[0]) == 1 else 'C0',
65+
'rlocus.plotstr': 'b' if int(mpl.__version__[0]) == 1 else 'C0',
6766
'rlocus.print_gain': True,
6867
'rlocus.plot': True
6968
}
7069

7170

7271
# Main function: compute a root locus diagram
7372
def root_locus(sys, kvect=None, xlim=None, ylim=None,
74-
plotstr=None, plot=True, print_gain=None, grid=None, **kwargs):
73+
plotstr=None, plot=True, print_gain=None, grid=None, ax=None,
74+
**kwargs):
7575

7676
"""Root locus plot
7777
@@ -96,6 +96,8 @@ def root_locus(sys, kvect=None, xlim=None, ylim=None,
9696
branches, calculate gain, damping and print.
9797
grid : bool
9898
If True plot omega-damping grid. Default is False.
99+
ax : Matplotlib axis
100+
axis on which to create root locus plot
99101
100102
Returns
101103
-------
@@ -143,42 +145,33 @@ def root_locus(sys, kvect=None, xlim=None, ylim=None,
143145
# Create the Plot
144146
if plot:
145147
if sisotool:
146-
f = kwargs['fig']
147-
ax = f.axes[1]
148-
148+
fig = kwargs['fig']
149+
ax = fig.axes[1]
149150
else:
150-
figure_number = pylab.get_fignums()
151-
figure_title = [
152-
pylab.figure(numb).canvas.get_window_title()
153-
for numb in figure_number]
154-
new_figure_name = "Root Locus"
155-
rloc_num = 1
156-
while new_figure_name in figure_title:
157-
new_figure_name = "Root Locus " + str(rloc_num)
158-
rloc_num += 1
159-
f = pylab.figure(new_figure_name)
160-
ax = pylab.axes()
151+
if ax is None:
152+
ax = plt.gca()
153+
fig = ax.figure
154+
ax.set_title('Root Locus')
161155

162156
if print_gain and not sisotool:
163-
f.canvas.mpl_connect(
157+
fig.canvas.mpl_connect(
164158
'button_release_event',
165-
partial(_RLClickDispatcher, sys=sys, fig=f,
166-
ax_rlocus=f.axes[0], plotstr=plotstr))
167-
159+
partial(_RLClickDispatcher, sys=sys, fig=fig,
160+
ax_rlocus=fig.axes[0], plotstr=plotstr))
168161
elif sisotool:
169-
f.axes[1].plot(
162+
fig.axes[1].plot(
170163
[root.real for root in start_mat],
171164
[root.imag for root in start_mat],
172165
'm.', marker='s', markersize=8, zorder=20, label='gain_point')
173-
f.suptitle(
166+
fig.suptitle(
174167
"Clicked at: %10.4g%+10.4gj gain: %10.4g damp: %10.4g" %
175168
(start_mat[0][0].real, start_mat[0][0].imag,
176169
1, -1 * start_mat[0][0].real / abs(start_mat[0][0])),
177-
fontsize=12 if int(matplotlib.__version__[0]) == 1 else 10)
178-
f.canvas.mpl_connect(
170+
fontsize=12 if int(mpl.__version__[0]) == 1 else 10)
171+
fig.canvas.mpl_connect(
179172
'button_release_event',
180-
partial(_RLClickDispatcher, sys=sys, fig=f,
181-
ax_rlocus=f.axes[1], plotstr=plotstr,
173+
partial(_RLClickDispatcher, sys=sys, fig=fig,
174+
ax_rlocus=fig.axes[1], plotstr=plotstr,
182175
sisotool=sisotool,
183176
bode_plot_params=kwargs['bode_plot_params'],
184177
tvect=kwargs['tvect']))
@@ -580,7 +573,7 @@ def _RLFeedbackClicksPoint(event, sys, fig, ax_rlocus, sisotool=False):
580573
fig.suptitle(
581574
"Clicked at: %10.4g%+10.4gj gain: %10.4g damp: %10.4g" %
582575
(s.real, s.imag, K.real, -1 * s.real / abs(s)),
583-
fontsize=12 if int(matplotlib.__version__[0]) == 1 else 10)
576+
fontsize=12 if int(mpl.__version__[0]) == 1 else 10)
584577

585578
# Remove the previous line
586579
_removeLine(label='gain_point', ax=ax_rlocus)
@@ -609,7 +602,7 @@ def _removeLine(label, ax):
609602

610603
def _sgrid_func(fig=None, zeta=None, wn=None):
611604
if fig is None:
612-
fig = pylab.gcf()
605+
fig = plt.gcf()
613606
ax = fig.gca()
614607
else:
615608
ax = fig.axes[1]

control/tests/rlocus_test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ def test_without_gains(self):
4949
def test_root_locus_zoom(self):
5050
"""Check the zooming functionality of the Root locus plot"""
5151
system = TransferFunction([1000], [1, 25, 100, 0])
52+
plt.figure()
5253
root_locus(system)
5354
fig = plt.gcf()
5455
ax_rlocus = fig.axes[0]

0 commit comments

Comments
 (0)