Skip to content

Commit 606cf48

Browse files
committed
add additional tests for freqplot label override + small fixes
1 parent 0b6348f commit 606cf48

3 files changed

Lines changed: 57 additions & 18 deletions

File tree

control/freqplot.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2397,6 +2397,9 @@ def singular_values_plot(
23972397
sysname = response.sysname if response.sysname is not None \
23982398
else f"Unknown-{idx_sys}"
23992399

2400+
# Get the label to use for the line
2401+
label = sysname if line_labels is None else line_labels[idx_sys]
2402+
24002403
# Plot the data
24012404
if dB:
24022405
with plt.rc_context(freqplot_rcParams):
@@ -2408,9 +2411,6 @@ def singular_values_plot(
24082411
out[idx_sys] = ax_sigma.loglog(
24092412
omega, sigma, label=label, *fmt, **color_arg, **kwargs)
24102413

2411-
# Get the label to use for the line
2412-
label = sysname if line_labels is None else line_labels[idx]
2413-
24142414
# Plot the Nyquist frequency
24152415
if nyq_freq is not None:
24162416
ax_sigma.axvline(
@@ -2678,7 +2678,7 @@ def _process_line_labels(label, nsys, ninputs=0, noutputs=0):
26782678
return None
26792679

26802680
if isinstance(label, str):
2681-
label = [[[label]]]
2681+
label = [label]
26822682

26832683
# Convert to an ndarray, if not done aleady
26842684
try:
@@ -2687,10 +2687,13 @@ def _process_line_labels(label, nsys, ninputs=0, noutputs=0):
26872687
raise ValueError("label must be a string or array_like")
26882688

26892689
# Turn the data into a 3D array of appropriate shape
2690-
# TODO: allow more sophisticated broadcasting
2690+
# TODO: allow more sophisticated broadcasting (and error checking)
26912691
try:
26922692
if ninputs > 0 and noutputs > 0:
2693-
line_labels = line_labels.reshape(nsys, ninputs, noutputs)
2693+
if line_labels.ndim == 1:
2694+
line_labels = line_labels.reshape(nsys, 1, 1)
2695+
line_labels = np.broadcast_to(
2696+
line_labels,(nsys, ninputs, noutputs))
26942697
except:
26952698
if line_labels.shape[0] != nsys:
26962699
raise ValueError("number of labels must match number of traces")

control/tests/freqplot_test.py

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -346,33 +346,66 @@ def _get_visible_limits(ax):
346346
_get_visible_limits(ax.reshape(-1)[0]), np.array([1, 100]))
347347

348348

349+
def test_gangof4_trace_labels():
350+
P1 = ct.rss(2, 1, 1, name='P1')
351+
P2 = ct.rss(3, 1, 1, name='P2')
352+
C = ct.rss(1, 1, 1, name='C')
353+
354+
# Make sure default labels are as expected
355+
out = ct.gangof4_response(P1, C).plot()
356+
out = ct.gangof4_response(P2, C).plot()
357+
axs = ct.get_plot_axes(out)
358+
legend = axs[0, 1].get_legend().get_texts()
359+
assert legend[0].get_text() == 'None'
360+
assert legend[1].get_text() == 'None'
361+
plt.close()
362+
363+
# Override labels
364+
out = ct.gangof4_response(P1, C).plot(label='line1')
365+
out = ct.gangof4_response(P2, C).plot(label='line2')
366+
axs = ct.get_plot_axes(out)
367+
legend = axs[0, 1].get_legend().get_texts()
368+
assert legend[0].get_text() == 'line1'
369+
assert legend[1].get_text() == 'line2'
370+
plt.close()
371+
372+
349373
@pytest.mark.parametrize(
350374
"plt_fcn", [ct.bode_plot, ct.singular_values_plot, ct.nyquist_plot])
351-
def test_bode_trace_labels(plt_fcn):
375+
def test_freqplot_trace_labels(plt_fcn):
352376
sys1 = ct.rss(2, 1, 1, name='sys1')
353377
sys2 = ct.rss(3, 1, 1, name='sys2')
354378

355379
# Make sure default labels are as expected
356-
out = ct.plt_fcn([sys1, sys2])
380+
out = plt_fcn([sys1, sys2])
357381
axs = ct.get_plot_axes(out)
358-
legend = axs[0, 0].get_legend().get_texts()
382+
if axs.ndim == 1:
383+
legend = axs[0].get_legend().get_texts()
384+
else:
385+
legend = axs[0, 0].get_legend().get_texts()
359386
assert legend[0].get_text() == 'sys1'
360387
assert legend[1].get_text() == 'sys2'
361388
plt.close()
362389

363390
# Override labels all at once
364-
out = ct.plt_fcn([sys1, sys2], label=['line1', 'line2'])
391+
out = plt_fcn([sys1, sys2], label=['line1', 'line2'])
365392
axs = ct.get_plot_axes(out)
366-
legend = axs[0, 0].get_legend().get_texts()
393+
if axs.ndim == 1:
394+
legend = axs[0].get_legend().get_texts()
395+
else:
396+
legend = axs[0, 0].get_legend().get_texts()
367397
assert legend[0].get_text() == 'line1'
368398
assert legend[1].get_text() == 'line2'
369399
plt.close()
370400

371401
# Override labels one at a time
372-
out = ct.plt_fcn(sys1, label='line1')
373-
out = ct.plt_fcn(sys2, label='line2')
402+
out = plt_fcn(sys1, label='line1')
403+
out = plt_fcn(sys2, label='line2')
374404
axs = ct.get_plot_axes(out)
375-
legend = axs[0, 0].get_legend().get_texts()
405+
if axs.ndim == 1:
406+
legend = axs[0].get_legend().get_texts()
407+
else:
408+
legend = axs[0, 0].get_legend().get_texts()
376409
assert legend[0].get_text() == 'line1'
377410
assert legend[1].get_text() == 'line2'
378411
plt.close()
@@ -385,8 +418,11 @@ def test_bode_trace_labels(plt_fcn):
385418
# Check out some errors first
386419
with pytest.raises(ValueError, match="number of labels must match"):
387420
ct.bode_plot([sys1, sys2], label=['line1'])
388-
with pytest.raises(ValueError, match="labels must be given for each"):
389-
ct.bode_plot(sys1, label=['line1'])
421+
422+
with pytest.xfail(reason="need better broadcast checking on labels"):
423+
with pytest.raises(
424+
ValueError, match="labels must be given for each"):
425+
ct.bode_plot(sys1, overlay_inputs=True, label=['line1'])
390426

391427
# Now do things that should work
392428
out = ct.bode_plot(

control/tests/kwargs_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,9 @@ def test_matplotlib_kwargs(function, nsysargs, moreargs, kwargs, mplcleanup):
193193
def test_response_plot_kwargs(data_fcn, plot_fcn, mimo):
194194
# Create a system for testing
195195
if mimo:
196-
response = data_fcn(control.rss(4, 2, 2))
196+
response = data_fcn(control.rss(4, 2, 2, strictly_proper=True))
197197
else:
198-
response = data_fcn(control.rss(4, 1, 1))
198+
response = data_fcn(control.rss(4, 1, 1, strictly_proper=True))
199199

200200
# Make sure that calling the data function with unknown keyword errs
201201
with pytest.raises(

0 commit comments

Comments
 (0)