Skip to content

Commit 77babe9

Browse files
committed
Fix: handle MatplotlibDeprecationWarning for mlab.find and .frange
Reimplemented mlab.find as private _find. Replaced mlab.frange calls with equivalent numpy.linspace call, and corrected phaseplot.phase_plot docs for how the X and Y arguments are used.
1 parent 0d94329 commit 77babe9

2 files changed

Lines changed: 21 additions & 14 deletions

File tree

control/phaseplot.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,20 @@
3939

4040
import numpy as np
4141
import matplotlib.pyplot as mpl
42-
from matplotlib.mlab import frange, find
42+
4343
from scipy.integrate import odeint
4444
from .exception import ControlNotImplemented
4545

4646
__all__ = ['phase_plot', 'box_grid']
4747

48+
49+
def _find(condition):
50+
"""Returns indices where ravel(a) is true.
51+
Private implementation of deprecated matplotlib.mlab.find
52+
"""
53+
return np.nonzero(np.ravel(condition))[0]
54+
55+
4856
def phase_plot(odefun, X=None, Y=None, scale=1, X0=None, T=None,
4957
lingrid=None, lintime=None, logtime=None, timepts=None,
5058
parms=(), verbose=True):
@@ -70,11 +78,11 @@ def phase_plot(odefun, X=None, Y=None, scale=1, X0=None, T=None,
7078
dxdt = F(x, t) that accepts a state x of dimension 2 and
7179
returns a derivative dx/dt of dimension 2.
7280
73-
X, Y: ndarray, optional
74-
Two 1-D arrays representing x and y coordinates of a grid.
75-
These arguments are passed to meshgrid and generate the lists
76-
of points at which the vector field is plotted. If absent (or
77-
None), the vector field is not plotted.
81+
X, Y: 3-element sequences, optional, as [start, stop, npts]
82+
Two 3-element sequences specifying x and y coordinates of a
83+
grid. These arguments are passed to linspace and meshgrid to
84+
generate the points at which the vector field is plotted. If
85+
absent (or None), the vector field is not plotted.
7886
7987
scale: float, optional
8088
Scale size of arrows; default = 1
@@ -145,8 +153,8 @@ def phase_plot(odefun, X=None, Y=None, scale=1, X0=None, T=None,
145153
#! TODO: Add sanity checks
146154
elif (X is not None and Y is not None):
147155
(x1, x2) = np.meshgrid(
148-
frange(X[0], X[1], float(X[1]-X[0])/X[2]),
149-
frange(Y[0], Y[1], float(Y[1]-Y[0])/Y[2]));
156+
np.linspace(X[0], X[1], X[2]),
157+
np.linspace(Y[0], Y[1], Y[2]))
150158
else:
151159
# If we weren't given any grid points, don't plot arrows
152160
Narrows = 0;
@@ -234,12 +242,12 @@ def phase_plot(odefun, X=None, Y=None, scale=1, X0=None, T=None,
234242
elif (logtimeFlag):
235243
# Use an exponential time vector
236244
# MATLAB: tind = find(time < (j-k) / lambda, 1, 'last');
237-
tarr = find(time < (j-k) / timefactor);
245+
tarr = _find(time < (j-k) / timefactor);
238246
tind = tarr[-1] if len(tarr) else 0;
239247
elif (timeptsFlag):
240248
# Use specified time points
241249
# MATLAB: tind = find(time < Y[j], 1, 'last');
242-
tarr = find(time < timepts[j]);
250+
tarr = _find(time < timepts[j]);
243251
tind = tarr[-1] if len(tarr) else 0;
244252

245253
# For tailless arrows, skip the first point
@@ -295,8 +303,8 @@ def box_grid(xlimp, ylimp):
295303
box defined by the corners [xmin ymin] and [xmax ymax].
296304
"""
297305

298-
sx10 = frange(xlimp[0], xlimp[1], float(xlimp[1]-xlimp[0])/xlimp[2])
299-
sy10 = frange(ylimp[0], ylimp[1], float(ylimp[1]-ylimp[0])/ylimp[2])
306+
sx10 = np.linspace(xlimp[0], xlimp[1], xlimp[2])
307+
sy10 = np.linspace(ylimp[0], ylimp[1], ylimp[2])
300308

301309
sx1 = np.hstack((0, sx10, 0*sy10+sx10[0], sx10, 0*sy10+sx10[-1]))
302310
sx2 = np.hstack((0, 0*sx10+sy10[0], sy10, 0*sx10+sy10[-1], sy10))

examples/genswitch.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import numpy as np
99
import matplotlib.pyplot as mpl
1010
from scipy.integrate import odeint
11-
from matplotlib.mlab import frange
1211
from control import phase_plot, box_grid
1312

1413
# Simple model of a genetic switch
@@ -34,7 +33,7 @@ def genswitch(y, t, mu=4, n=2):
3433
sol2 = odeint(genswitch, sol1[-1,:] + [2, -2], tim2)
3534

3635
# First plot out the curves that define the equilibria
37-
u = frange(0, 4.5, 0.1)
36+
u = np.linspace(0, 4.5, 46)
3837
f = np.divide(mu, (1 + u**n)) # mu / (1 + u^n), elementwise
3938

4039
mpl.figure(1); mpl.clf();

0 commit comments

Comments
 (0)