55from .lti import issiso
66import matplotlib
77import matplotlib .pyplot as plt
8-
9- def sisotool (sys , kvect = None , xlim = None , ylim = None , plotstr_rlocus = 'b' if int (matplotlib .__version__ [0 ]) == 1 else 'C0' ,rlocus_grid = False , omega = None , dB = None , Hz = None , deg = None , omega_limits = None , omega_num = None ,margins = True , tvect = None ):
10-
8+ import warnings
9+
10+ def sisotool (sys , kvect = None , xlim_rlocus = None , ylim_rlocus = None , plotstr_rlocus = 'b' if int (matplotlib .__version__ [0 ]) == 1 else 'C0' ,rlocus_grid = False , omega = None , dB = None , Hz = None , deg = None , omega_limits = None , omega_num = None ,margins_bode = True , tvect = None ):
11+
12+ """Sisotool
13+
14+ Sisotool style collection of plots inspired by the matlab sisotool.
15+ The left two plots contain the bode magnitude and phase diagrams.
16+ The top right plot is a clickable root locus plot, clicking on the
17+ root locus will change the gain of the system. The bottom left plot
18+ shows a closed loop time response.
19+
20+ Parameters
21+ ----------
22+ sys : LTI object
23+ Linear input/output systems (SISO only)
24+ kvect : list or ndarray, optional
25+ List of gains to use for plotting root locus
26+ xlim_rlocus : tuple or list, optional
27+ control of x-axis range, normally with tuple (see matplotlib.axes)
28+ ylim_rlocus : tuple or list, optional
29+ control of y-axis range
30+ plotstr_rlocus : Additional options to matplotlib
31+ plotting style for the root locus plot(color, linestyle, etc)
32+ rlocus_grid: boolean (default = False)
33+ If True plot s-plane grid.
34+ omega : freq_range
35+ Range of frequencies in rad/sec for the bode plot
36+ dB : boolean
37+ If True, plot result in dB for the bode plot
38+ Hz : boolean
39+ If True, plot frequency in Hz for the bode plot (omega must be provided in rad/sec)
40+ deg : boolean
41+ If True, plot phase in degrees for the bode plot (else radians)
42+ omega_limits: tuple, list, ... of two values
43+ Limits of the to generate frequency vector.
44+ If Hz=True the limits are in Hz otherwise in rad/s.
45+ omega_num: int
46+ number of samples
47+ margins_bode : boolean
48+ If True, plot gain and phase margin in the bode plot
49+ tvect : list or ndarray, optional
50+ List of timesteps to use for closed loop step response
51+
52+ Examples
53+ --------
54+ >>> sys = tf([1000], [1,25,100,0])
55+ >>> sisotool(sys)
56+
57+ """
1158 from .rlocus import root_locus
1259
1360 # Check if it is a single SISO system
@@ -30,14 +77,14 @@ def sisotool(sys, kvect = None, xlim = None, ylim = None, plotstr_rlocus = 'b' i
3077 'omega_num' : omega_num ,
3178 'sisotool' : True ,
3279 'fig' : fig ,
33- 'margins' : margins
80+ 'margins' : margins_bode
3481 }
3582
3683 # First time call to setup the bode and step response plots
3784 _SisotoolUpdate (sys , fig ,1 if kvect is None else kvect [0 ],bode_plot_params )
3885
3986 # Setup the root-locus plot window
40- root_locus (sys ,kvect = kvect ,xlim = xlim ,ylim = ylim ,plotstr = plotstr_rlocus ,grid = rlocus_grid ,fig = fig ,bode_plot_params = bode_plot_params ,tvect = tvect ,sisotool = True )
87+ root_locus (sys ,kvect = kvect ,xlim = xlim_rlocus ,ylim = ylim_rlocus ,plotstr = plotstr_rlocus ,grid = rlocus_grid ,fig = fig ,bode_plot_params = bode_plot_params ,tvect = tvect ,sisotool = True )
4188
4289def _SisotoolUpdate (sys ,fig ,K ,bode_plot_params ,tvect = None ):
4390
@@ -50,7 +97,11 @@ def _SisotoolUpdate(sys,fig,K,bode_plot_params,tvect=None):
5097
5198 # Get the subaxes and clear them
5299 ax_mag ,ax_rlocus ,ax_phase ,ax_step = fig .axes [0 ],fig .axes [1 ],fig .axes [2 ],fig .axes [3 ]
53- ax_mag .cla (),ax_phase .cla (),ax_step .cla ()
100+
101+ # Catch matplotlib 2.1.x and higher userwarnings when clearing a log axis
102+ with warnings .catch_warnings ():
103+ warnings .simplefilter ("ignore" )
104+ ax_step .clear (), ax_mag .clear (), ax_phase .clear ()
54105
55106 # Update the bodeplot
56107 bode_plot_params ['syslist' ] = sys * K .real
0 commit comments