@@ -1501,7 +1501,7 @@ def nyquist_response(
1501
1501
1502
1502
1503
1503
def nyquist_plot (
1504
- data , omega = None , plot = None , label_freq = 0 , color = None ,
1504
+ data , omega = None , plot = None , label_freq = 0 , color = None , label = None ,
1505
1505
return_contour = None , title = None , legend_loc = 'upper right' , ** kwargs ):
1506
1506
"""Nyquist plot for a system.
1507
1507
@@ -1590,6 +1590,11 @@ def nyquist_plot(
1590
1590
imaginary axis. Portions of the Nyquist plot corresponding to indented
1591
1591
portions of the contour are plotted using a different line style.
1592
1592
1593
+ label : str or array-like of str
1594
+ If present, replace automatically generated label(s) with the given
1595
+ label(s). If sysdata is a list, strings should be specified for each
1596
+ system.
1597
+
1593
1598
label_freq : int, optiona
1594
1599
Label every nth frequency on the plot. If not specified, no labels
1595
1600
are generated.
@@ -1739,6 +1744,9 @@ def _parse_linestyle(style_name, allow_false=False):
1739
1744
if not isinstance (data , (list , tuple )):
1740
1745
data = [data ]
1741
1746
1747
+ # Process label keyword
1748
+ line_labels = _process_line_labels (label , len (data ))
1749
+
1742
1750
# If we are passed a list of systems, compute response first
1743
1751
if all ([isinstance (
1744
1752
sys , (StateSpace , TransferFunction , FrequencyResponseData ))
@@ -1804,12 +1812,14 @@ def _parse_linestyle(style_name, allow_false=False):
1804
1812
reg_mask , abs (resp ) > max_curve_magnitude )
1805
1813
resp [rescale ] *= max_curve_magnitude / abs (resp [rescale ])
1806
1814
1815
+ # Get the label to use for the line
1816
+ label = response .sysname if line_labels is None else line_labels [idx ]
1817
+
1807
1818
# Plot the regular portions of the curve (and grab the color)
1808
1819
x_reg = np .ma .masked_where (reg_mask , resp .real )
1809
1820
y_reg = np .ma .masked_where (reg_mask , resp .imag )
1810
1821
p = plt .plot (
1811
- x_reg , y_reg , primary_style [0 ], color = color ,
1812
- label = response .sysname , ** kwargs )
1822
+ x_reg , y_reg , primary_style [0 ], color = color , label = label , ** kwargs )
1813
1823
c = p [0 ].get_color ()
1814
1824
out [idx ] += p
1815
1825
@@ -2211,7 +2221,7 @@ def singular_values_response(
2211
2221
2212
2222
def singular_values_plot (
2213
2223
data , omega = None , * fmt , plot = None , omega_limits = None , omega_num = None ,
2214
- title = None , legend_loc = 'center right' , ** kwargs ):
2224
+ label = None , title = None , legend_loc = 'center right' , ** kwargs ):
2215
2225
"""Plot the singular values for a system.
2216
2226
2217
2227
Plot the singular values as a function of frequency for a system or
@@ -2257,6 +2267,10 @@ def singular_values_plot(
2257
2267
grid : bool
2258
2268
If True, plot grid lines on gain and phase plots. Default is set by
2259
2269
`config.defaults['freqplot.grid']`.
2270
+ label : str or array-like of str
2271
+ If present, replace automatically generated label(s) with the given
2272
+ label(s). If sysdata is a list, strings should be specified for each
2273
+ system.
2260
2274
omega_limits : array_like of two values
2261
2275
Set limits for plotted frequency range. If Hz=True the limits
2262
2276
are in Hz otherwise in rad/s.
@@ -2306,6 +2320,9 @@ def singular_values_plot(
2306
2320
2307
2321
responses = data
2308
2322
2323
+ # Process label keyword
2324
+ line_labels = _process_line_labels (label , len (data ))
2325
+
2309
2326
# Process (legacy) plot keyword
2310
2327
if plot is not None :
2311
2328
warnings .warn (
@@ -2385,11 +2402,14 @@ def singular_values_plot(
2385
2402
with plt .rc_context (freqplot_rcParams ):
2386
2403
out [idx_sys ] = ax_sigma .semilogx (
2387
2404
omega , 20 * np .log10 (sigma ), * fmt ,
2388
- label = sysname , ** color_arg , ** kwargs )
2405
+ label = label , ** color_arg , ** kwargs )
2389
2406
else :
2390
2407
with plt .rc_context (freqplot_rcParams ):
2391
2408
out [idx_sys ] = ax_sigma .loglog (
2392
- omega , sigma , label = sysname , * fmt , ** color_arg , ** kwargs )
2409
+ omega , sigma , label = label , * fmt , ** color_arg , ** kwargs )
2410
+
2411
+ # Get the label to use for the line
2412
+ label = sysname if line_labels is None else line_labels [idx ]
2393
2413
2394
2414
# Plot the Nyquist frequency
2395
2415
if nyq_freq is not None :
@@ -2653,7 +2673,7 @@ def _get_line_labels(ax, use_color=True):
2653
2673
2654
2674
2655
2675
# Turn label keyword into array indexed by trace, output, input
2656
- def _process_line_labels (label , nsys , ninput , noutput ):
2676
+ def _process_line_labels (label , nsys , ninputs = 0 , noutputs = 0 ):
2657
2677
if label is None :
2658
2678
return None
2659
2679
@@ -2669,7 +2689,8 @@ def _process_line_labels(label, nsys, ninput, noutput):
2669
2689
# Turn the data into a 3D array of appropriate shape
2670
2690
# TODO: allow more sophisticated broadcasting
2671
2691
try :
2672
- line_labels = line_labels .reshape (nsys , ninput , noutput )
2692
+ if ninputs > 0 and noutputs > 0 :
2693
+ line_labels = line_labels .reshape (nsys , ninputs , noutputs )
2673
2694
except :
2674
2695
if line_labels .shape [0 ] != nsys :
2675
2696
raise ValueError ("number of labels must match number of traces" )
0 commit comments