118118
119119def 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\n Freq: %.2f %s' %
0 commit comments