Skip to content

Commit c5fa4e6

Browse files
committed
Bugfixes with ax, fig in sgrid, zgrid + ylim on rlocus
1 parent cc97f4b commit c5fa4e6

File tree

2 files changed

+34
-30
lines changed

2 files changed

+34
-30
lines changed

control/grid.py

+19-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import numpy as np
2-
from numpy import cos, sin, sqrt, linspace, pi, exp
2+
from numpy import cos, sin, sqrt, pi, exp
33
import matplotlib.pyplot as plt
44
from mpl_toolkits.axisartist import SubplotHost
55
from mpl_toolkits.axisartist.grid_helper_curvelinear \
@@ -19,10 +19,9 @@ def __call__(self, direction, factor, values):
1919

2020

2121
class ModifiedExtremeFinderCycle(angle_helper.ExtremeFinderCycle):
22-
'''Changed to allow only left hand-side polar grid
23-
24-
https://matplotlib.org/_modules/mpl_toolkits/axisartist/angle_helper.html#ExtremeFinderCycle.__call__
25-
'''
22+
# Changed to allow only left hand-side polar grid
23+
# https://matplotlib.org/_modules/mpl_toolkits/axisartist/angle_helper.html#ExtremeFinderCycle.__call__
24+
2625
def __call__(self, transform_xy, x1, y1, x2, y2):
2726
x, y = np.meshgrid(
2827
np.linspace(x1, x2, self.nx), np.linspace(y1, y2, self.ny))
@@ -65,11 +64,16 @@ def __call__(self, transform_xy, x1, y1, x2, y2):
6564
return lon_min, lon_max, lat_min, lat_max
6665

6766

68-
def sgrid():
67+
def sgrid(ax=None):
68+
"""Draws continuous time damping and frequency grid"""
6969
# From matplotlib demos:
7070
# https://matplotlib.org/gallery/axisartist/demo_curvelinear_grid.html
7171
# https://matplotlib.org/gallery/axisartist/demo_floating_axis.html
7272

73+
if ax is None:
74+
ax = plt.gca()
75+
fig = ax.figure
76+
7377
# PolarAxes.PolarTransform takes radian. However, we want our coordinate
7478
# system in degree
7579
tr = Affine2D().scale(np.pi/180., 1.) + PolarAxes.PolarTransform()
@@ -144,10 +148,11 @@ def _final_setup(ax):
144148
ax.set_ylabel('Imaginary')
145149
ax.axhline(y=0, color='black', lw=1)
146150
ax.axvline(x=0, color='black', lw=1)
147-
plt.axis('equal')
151+
ax.axis('equal')
148152

149153

150154
def nogrid():
155+
# TODO: this doesn't look safe. convert to take ax argument
151156
f = plt.gcf()
152157
ax = plt.axes()
153158

@@ -156,19 +161,19 @@ def nogrid():
156161

157162

158163
def zgrid(zetas=None, wns=None, ax=None):
159-
'''Draws discrete damping and frequency grid'''
164+
'''Draws discrete time damping and frequency grid'''
160165

161-
fig = plt.gcf()
162166
if ax is None:
163-
ax = fig.gca()
167+
ax = plt.gca()
168+
fig = ax.figure
164169

165170
# Constant damping lines
166171
if zetas is None:
167-
zetas = linspace(0, 0.9, 10)
172+
zetas = np.linspace(0, 0.9, 10)
168173
for zeta in zetas:
169174
# Calculate in polar coordinates
170175
factor = zeta/sqrt(1-zeta**2)
171-
x = linspace(0, sqrt(1-zeta**2), 200)
176+
x = np.linspace(0, sqrt(1-zeta**2), 200)
172177
ang = pi*x
173178
mag = exp(-pi*factor*x)
174179
# Draw upper part in retangular coordinates
@@ -188,10 +193,10 @@ def zgrid(zetas=None, wns=None, ax=None):
188193

189194
# Constant natural frequency lines
190195
if wns is None:
191-
wns = linspace(0, 1, 10)
196+
wns = np.linspace(0, 1, 10)
192197
for a in wns:
193198
# Calculate in polar coordinates
194-
x = linspace(-pi/2, pi/2, 200)
199+
x = np.linspace(-pi/2, pi/2, 200)
195200
ang = pi*a*sin(x)
196201
mag = exp(-pi*a*cos(x))
197202
# Draw in retangular coordinates

control/rlocus.py

+15-16
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,15 @@
6767
# Default values for module parameters
6868
_rlocus_defaults = {
6969
'rlocus.grid': True,
70-
'rlocus.plotstr': 'b' if int(mpl.__version__[0]) == 1 else 'C0',
70+
'rlocus.plotstr': '',
7171
'rlocus.print_gain': True,
7272
'rlocus.plot': True
7373
}
7474

7575

7676
# Main function: compute a root locus diagram
77-
def root_locus(sys, kvect=None, xlim=None, ylim=None,
78-
plotstr=None, plot=True, print_gain=None, grid=None, ax=None,
77+
def root_locus(sys, kvect=None, xlim=None, ylim=None, plotstr=None,
78+
plot=True, print_gain=None, grid=None, ax=None,
7979
**kwargs):
8080

8181
"""Root locus plot
@@ -104,7 +104,7 @@ def root_locus(sys, kvect=None, xlim=None, ylim=None,
104104
If True (default), report mouse clicks when close to the root locus
105105
branches, calculate gain, damping and print.
106106
grid : bool
107-
If True plot omega-damping grid. Default is False.
107+
If True (default) plot omega-damping grid.
108108
ax : :class:`matplotlib.axes.Axes`
109109
Axes on which to create root locus plot
110110
@@ -143,11 +143,12 @@ def root_locus(sys, kvect=None, xlim=None, ylim=None,
143143
(nump, denp) = _systopoly1d(sys_loop)
144144

145145
# if discrete-time system and if xlim and ylim are not given,
146-
# that we a view of the unit circle
147-
if xlim is None and isdtime(sys, strict=True):
148-
xlim = (-1.2, 1.2)
149-
if ylim is None and isdtime(sys, strict=True):
150-
xlim = (-1.3, 1.3)
146+
# make sure that we a view of the unit circle
147+
if isdtime(sys, strict=True):
148+
if xlim is None:
149+
xlim = (-1.2, 1.2)
150+
if ylim is None:
151+
ylim = (-1.3, 1.3)
151152

152153
if kvect is None:
153154
start_mat = _RLFindRoots(nump, denp, [1])
@@ -168,8 +169,8 @@ def root_locus(sys, kvect=None, xlim=None, ylim=None,
168169
else:
169170
if ax is None:
170171
ax = plt.gca()
171-
fig = ax.figure
172-
ax.set_title('Root Locus')
172+
fig = ax.figure
173+
ax.set_title('Root Locus')
173174

174175
if print_gain and not sisotool:
175176
fig.canvas.mpl_connect(
@@ -642,9 +643,7 @@ def _removeLine(label, ax):
642643
def _sgrid_func(fig=None, zeta=None, wn=None):
643644
if fig is None:
644645
fig = plt.gcf()
645-
ax = fig.gca()
646-
else:
647-
ax = fig.axes[1]
646+
ax = fig.gca()
648647

649648
# Get locator function for x-axis, y-axis tick marks
650649
xlocator = ax.get_xaxis().get_major_locator()
@@ -748,7 +747,7 @@ def _default_zetas(xlim, ylim):
748747

749748

750749
def _default_wn(xloc, yloc, max_lines=7):
751-
"""Return default wn for root locus plot
750+
"""Return default natural frequencies for root locus plot
752751
753752
This function computes a list of natural frequencies based on the grid
754753
parameters of the graph.
@@ -769,7 +768,7 @@ def _default_wn(xloc, yloc, max_lines=7):
769768
770769
"""
771770
sep = xloc[1]-xloc[0] # separation between x-ticks
772-
771+
773772
# Decide whether to use the x or y axis for determining wn
774773
if yloc[-1] / sep > max_lines*10:
775774
# y-axis scale >> x-axis scale

0 commit comments

Comments
 (0)