@@ -201,8 +201,10 @@ def bode_plot(
201201
202202 Other Parameters
203203 ----------------
204- plot : bool
205- If True (default), plot magnitude and phase.
204+ plot : bool, optional
205+ (legacy) If given, `bode_plot` returns the legacy return values
206+ of magnitude, phase, and frequency. If False, just return the
207+ values with no plot.
206208 omega_limits : array_like of two values
207209 Limits of the to generate frequency vector. If Hz=True the limits
208210 are in Hz otherwise in rad/s.
@@ -232,22 +234,20 @@ def bode_plot(
232234
233235 Notes
234236 -----
235- 1. Alternatively, you may use the lower-level methods
236- :meth:`LTI.frequency_response` or ``sys(s)`` or ``sys(z)`` or to
237- generate the frequency response for a single system.
237+ 1. Starting with python-control version 0.10, `bode_plot`returns an
238+ array of lines instead of magnitude, phase, and frequency. To
239+ recover the # old behavior, call `bode_plot` with `plot=True`, which
240+ will force the legacy return values to be used (with a warning). To
241+ obtain just the frequency response of a system (or list of systems)
242+ without plotting, use the :func:`~control.frequency_response`
243+ command.
238244
239245 2. If a discrete time model is given, the frequency response is plotted
240246 along the upper branch of the unit circle, using the mapping ``z =
241247 exp(1j * omega * dt)`` where `omega` ranges from 0 to `pi/dt` and `dt`
242248 is the discrete timebase. If timebase not specified (``dt=True``),
243249 `dt` is set to 1.
244250
245- 3. The legacy version of this function is invoked if instead of passing
246- frequency response data, a system (or list of systems) is passed as
247- the first argument, or if the (deprecated) keyword `plot` is set to
248- True or False. The return value is then given as `mag`, `phase`,
249- `omega` for the plotted frequency response (SISO only).
250-
251251 Examples
252252 --------
253253 >>> G = ct.ss([[-1, -2], [3, -4]], [[5], [7]], [[6, 8]], [[9]])
@@ -315,18 +315,6 @@ def bode_plot(
315315 if not isinstance (data , (list , tuple )):
316316 data = [data ]
317317
318- # For backwards compatibility, allow systems in the data list
319- if all ([isinstance (
320- sys , (StateSpace , TransferFunction )) for sys in data ]):
321- data = frequency_response (
322- data , omega = omega , omega_limits = omega_limits ,
323- omega_num = omega_num )
324- warnings .warn (
325- "passing systems to `bode_plot` is deprecated; "
326- "use `frequency_response()`" , DeprecationWarning )
327- if plot is None :
328- plot = True # Keep track of legacy usage (see notes below)
329-
330318 #
331319 # Pre-process the data to be plotted (unwrap phase)
332320 #
@@ -337,6 +325,13 @@ def bode_plot(
337325 # the list of lines created, which is the new output for _plot functions.
338326 #
339327
328+ # If we were passed a list of systems, convert to data
329+ if all ([isinstance (
330+ sys , (StateSpace , TransferFunction )) for sys in data ]):
331+ data = frequency_response (
332+ data , omega = omega , omega_limits = omega_limits ,
333+ omega_num = omega_num , Hz = Hz )
334+
340335 # If plot_phase is not specified, check the data first, otherwise true
341336 if plot_phase is None :
342337 plot_phase = True if data [0 ].plot_phase is None else data [0 ].plot_phase
@@ -409,28 +404,25 @@ def bode_plot(
409404 #
410405 # There are three possibilities at this stage in the code:
411406 #
412- # * plot == True: either set explicitly by the user or we were passed a
413- # non-FRD system instead of data. Return mag, phase, omega, with a
414- # warning.
407+ # * plot == True: set explicitly by the user. Return mag, phase, omega,
408+ # with a warning.
415409 #
416410 # * plot == False: set explicitly by the user. Return mag, phase,
417411 # omega, with a warning.
418412 #
419- # * plot == None: this is the new default setting and if it hasn't been
420- # changed, then we use the v0.10+ standard of returning an array of
413+ # * plot == None: this is the new default setting. Return an array of
421414 # lines that were drawn.
422415 #
423- # The one case that can cause problems is that a user called
424- # `bode_plot` with an FRD system, didn't set the plot keyword
425- # explicitly, and expected mag, phase, omega as a return value. This
426- # is hopefully a rare case (it wasn't in any of our unit tests nor
427- # examples at the time of v0.10.0).
416+ # If `bode_plot` was called with no `plot` argument and the return
417+ # values were used, the new code will cause problems (you get an array
418+ # of lines instead of magnitude, phase, and frequency). To recover the
419+ # old behavior, call `bode_plot` with `plot=True`.
428420 #
429421 # All of this should be removed in v0.11+ when we get rid of deprecated
430422 # code.
431423 #
432424
433- if plot is True or plot is False :
425+ if plot is not None :
434426 warnings .warn (
435427 "`bode_plot` return values of mag, phase, omega is deprecated; "
436428 "use frequency_response()" , DeprecationWarning )
@@ -1828,8 +1820,8 @@ def _compute_curve_offset(resp, mask, max_offset):
18281820def gangof4_response (P , C , omega = None , Hz = False ):
18291821 """Compute the response of the "Gang of 4" transfer functions for a system.
18301822
1831- Generates a 2x2 plot showing the "Gang of 4" sensitivity functions
1832- [T, PS; CS, S].
1823+ Generates a 2x2 frequency response for the "Gang of 4" sensitivity
1824+ functions [T, PS; CS, S].
18331825
18341826 Parameters
18351827 ----------
@@ -1840,7 +1832,9 @@ def gangof4_response(P, C, omega=None, Hz=False):
18401832
18411833 Returns
18421834 -------
1843- None
1835+ response : :class:`~control.FrequencyResponseData`
1836+ Frequency response with inputs 'r' and 'd' and outputs 'y', and 'u'
1837+ representing the 2x2 matrix of transfer functions in the Gang of 4.
18441838
18451839 Examples
18461840 --------
@@ -1989,6 +1983,10 @@ def singular_values_plot(
19891983 Hz : bool
19901984 If True, plot frequency in Hz (omega must be provided in rad/sec).
19911985 Default value (False) set by config.defaults['freqplot.Hz'].
1986+ plot : bool, optional
1987+ (legacy) If given, `singular_values_plot` returns the legacy return
1988+ values of magnitude, phase, and frequency. If False, just return
1989+ the values with no plot.
19921990 *fmt : :func:`matplotlib.pyplot.plot` format string, optional
19931991 Passed to `matplotlib` as the format string for all lines in the plot.
19941992 The `omega` parameter must be present (use omega=None if needed).
@@ -2023,28 +2021,20 @@ def singular_values_plot(
20232021 freqplot_rcParams = config ._get_param (
20242022 'freqplot' , 'rcParams' , kwargs , _freqplot_defaults , pop = True )
20252023
2026- # Process legacy system arguments
2024+ # Convert systems into frequency responses
20272025 if any ([isinstance (response , (StateSpace , TransferFunction ))
20282026 for response in data ]):
2029- warnings .warn (
2030- "passing systems to `singular_values_plot` is deprecated; "
2031- "use `singular_values_response()`" , DeprecationWarning )
20322027 responses = singular_values_response (
20332028 data , omega = omega , omega_limits = omega_limits ,
20342029 omega_num = omega_num )
2035- legacy_usage = True
20362030 else :
20372031 responses = data
2038- legacy_usage = False
20392032
20402033 # Process (legacy) plot keyword
20412034 if plot is not None :
20422035 warnings .warn (
20432036 "`singular_values_plot` return values of sigma, omega is "
20442037 "deprecated; use singular_values_response()" , DeprecationWarning )
2045- legacy_usage = True
2046- else :
2047- plot = True
20482038
20492039 # Warn the user if we got past something that is not real-valued
20502040 if any ([not np .allclose (np .imag (response .fresp [:, 0 , :]), 0 )
@@ -2172,7 +2162,8 @@ def singular_values_plot(
21722162 with plt .rc_context (freqplot_rcParams ):
21732163 fig .suptitle (title )
21742164
2175- if legacy_usage :
2165+ # Legacy return processing
2166+ if plot is not None :
21762167 if len (responses ) == 1 :
21772168 return sigmas [0 ], omegas [0 ]
21782169 else :
0 commit comments