Skip to content

Commit bab5071

Browse files
committed
rename combine_traces to combine_time_responses, updated trace labels
1 parent 1a9e64f commit bab5071

File tree

4 files changed

+26
-26
lines changed

4 files changed

+26
-26
lines changed

control/tests/timeplot_test.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ def test_legend_map():
250250
title='MIMO step response with custom legend placement')
251251

252252

253-
def test_combine_traces():
253+
def test_combine_time_responses():
254254
sys_mimo = ct.rss(4, 2, 2)
255255
timepts = np.linspace(0, 10, 100)
256256

@@ -261,21 +261,21 @@ def test_combine_traces():
261261
U = np.vstack([np.cos(2*timepts), np.sin(timepts)])
262262
resp2 = ct.input_output_response(sys_mimo, timepts, U)
263263

264-
combresp1 = ct.combine_traces([resp1, resp2])
264+
combresp1 = ct.combine_time_responses([resp1, resp2])
265265
assert combresp1.ntraces == 2
266266
np.testing.assert_equal(combresp1.y[:, 0, :], resp1.y)
267267
np.testing.assert_equal(combresp1.y[:, 1, :], resp2.y)
268268

269269
# Combine two responses with ntrace != 0
270270
resp3 = ct.step_response(sys_mimo, timepts)
271271
resp4 = ct.step_response(sys_mimo, timepts)
272-
combresp2 = ct.combine_traces([resp3, resp4])
272+
combresp2 = ct.combine_time_responses([resp3, resp4])
273273
assert combresp2.ntraces == resp3.ntraces + resp4.ntraces
274274
np.testing.assert_equal(combresp2.y[:, 0:2, :], resp3.y)
275275
np.testing.assert_equal(combresp2.y[:, 2:4, :], resp4.y)
276276

277277
# Mixture
278-
combresp3 = ct.combine_traces([resp1, resp2, resp3])
278+
combresp3 = ct.combine_time_responses([resp1, resp2, resp3])
279279
assert combresp3.ntraces == resp3.ntraces + resp4.ntraces
280280
np.testing.assert_equal(combresp3.y[:, 0, :], resp1.y)
281281
np.testing.assert_equal(combresp3.y[:, 1, :], resp2.y)
@@ -286,30 +286,31 @@ def test_combine_traces():
286286

287287
# Rename the traces
288288
labels = ["T1", "T2", "T3", "T4"]
289-
combresp4 = ct.combine_traces([resp1, resp2, resp3], trace_labels=labels)
289+
combresp4 = ct.combine_time_responses(
290+
[resp1, resp2, resp3], trace_labels=labels)
290291
assert combresp4.trace_labels == labels
291292

292293
# Automatically generated trace label names and types
293294
resp5 = ct.step_response(sys_mimo, timepts)
294295
resp5.title = "test"
295296
resp5.trace_labels = None
296297
resp5.trace_types = None
297-
combresp5 = ct.combine_traces([resp1, resp5])
298+
combresp5 = ct.combine_time_responses([resp1, resp5])
298299
assert combresp5.trace_labels == [resp1.title] + \
299300
["test, trace 0", "test, trace 1"]
300301
assert combresp4.trace_types == [None, None, 'step', 'step']
301302

302303
with pytest.raises(ValueError, match="must have the same number"):
303304
resp = ct.step_response(ct.rss(4, 2, 3), timepts)
304-
combresp = ct.combine_traces([resp1, resp])
305+
combresp = ct.combine_time_responses([resp1, resp])
305306

306307
with pytest.raises(ValueError, match="trace labels does not match"):
307-
combresp = ct.combine_traces(
308+
combresp = ct.combine_time_responses(
308309
[resp1, resp2], trace_labels=["T1", "T2", "T3"])
309310

310311
with pytest.raises(ValueError, match="must have the same time"):
311312
resp = ct.step_response(ct.rss(4, 2, 3), timepts/2)
312-
combresp6 = ct.combine_traces([resp1, resp])
313+
combresp6 = ct.combine_time_responses([resp1, resp])
313314

314315

315316
@slycotonly
@@ -494,7 +495,7 @@ def test_errors():
494495
U = np.vstack([np.cos(2*timepts), np.sin(timepts)])
495496
resp2 = ct.input_output_response(sys_mimo, timepts, U)
496497

497-
ct.combine_traces(
498+
ct.combine_time_responses(
498499
[resp1, resp2], trace_labels=["Scenario #1", "Scenario #2"]).plot(
499500
transpose=True,
500501
title="I/O responses for 2x2 MIMO system, multiple traces "

control/timeplot.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
from . import config
1818

19-
__all__ = ['time_response_plot', 'combine_traces', 'get_plot_axes']
19+
__all__ = ['time_response_plot', 'combine_time_responses', 'get_plot_axes']
2020

2121
# Default font dictionary
2222
_timeplot_rcParams = mpl.rcParams.copy()
@@ -412,7 +412,7 @@ def _make_line_label(signal_index, signal_labels, trace_index):
412412
for i in range(ninputs):
413413
label = _make_line_label(i, data.input_labels, trace)
414414

415-
if add_initial_zero and data.trace_types \
415+
if add_initial_zero and data.ntraces > i \
416416
and data.trace_types[i] == 'step':
417417
x = np.hstack([np.array([data.time[0]]), data.time])
418418
y = np.hstack([np.array([0]), inputs[i][trace]])
@@ -606,7 +606,6 @@ def _make_line_label(signal_index, signal_labels, trace_index):
606606
labels = [line.get_label() for line in ax.get_lines()]
607607

608608
# Look for a common prefix (up to a space)
609-
# TODO: fix error in 1x2, overlay, transpose (Fig 24)
610609
common_prefix = commonprefix(labels)
611610
last_space = common_prefix.rfind(', ')
612611
if last_space < 0 or plot_inputs == 'overlay':
@@ -671,7 +670,7 @@ def _make_line_label(signal_index, signal_labels, trace_index):
671670
return out
672671

673672

674-
def combine_traces(response_list, trace_labels=None, title=None):
673+
def combine_time_responses(response_list, trace_labels=None, title=None):
675674
"""Combine multiple individual time responses into a multi-trace response.
676675
677676
This function combines multiple instances of :class:`TimeResponseData`

control/timeresp.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ def __init__(
427427
# Check and store trace labels, if present
428428
self.trace_labels = _process_labels(
429429
trace_labels, "trace", self.ntraces)
430-
self.trace_types = trace_types # TODO: rename to kind?
430+
self.trace_types = trace_types
431431

432432
# Figure out if the system is SISO
433433
if issiso is None:
@@ -1169,7 +1169,7 @@ def forced_response(sys, T=None, U=0., X0=0., transpose=False,
11691169
tout, yout, xout, U, issiso=sys.issiso(),
11701170
output_labels=sys.output_labels, input_labels=sys.input_labels,
11711171
state_labels=sys.state_labels, sysname=sys.name, plot_inputs=True,
1172-
title="Forced response for " + sys.name,
1172+
title="Forced response for " + sys.name, trace_types=['forced'],
11731173
transpose=transpose, return_x=return_x, squeeze=squeeze)
11741174

11751175

@@ -1386,8 +1386,7 @@ def step_response(sys, T=None, X0=0, input=None, output=None, T_num=None,
13861386
uout = np.empty((ninputs, ninputs, T.size))
13871387

13881388
# Simulate the response for each input
1389-
trace_labels = []
1390-
trace_types = []
1389+
trace_labels, trace_types = [], []
13911390
for i in range(sys.ninputs):
13921391
# If input keyword was specified, only simulate for that input
13931392
if isinstance(input, int) and i != input:
@@ -1761,7 +1760,7 @@ def initial_response(sys, T=None, X0=0, output=None, T_num=None,
17611760
response.t, yout, response.x, None, issiso=issiso,
17621761
output_labels=output_labels, input_labels=None,
17631762
state_labels=sys.state_labels, sysname=sys.name,
1764-
title="Initial response for " + sys.name,
1763+
title="Initial response for " + sys.name, trace_types=['initial'],
17651764
transpose=transpose, return_x=return_x, squeeze=squeeze)
17661765

17671766

@@ -1888,14 +1887,15 @@ def impulse_response(sys, T=None, input=None, output=None, T_num=None,
18881887
uout = np.full((ninputs, ninputs, np.asarray(T).size), None)
18891888

18901889
# Simulate the response for each input
1891-
trace_labels = []
1890+
trace_labels, trace_types = [], []
18921891
for i in range(sys.ninputs):
18931892
# If input keyword was specified, only handle that case
18941893
if isinstance(input, int) and i != input:
18951894
continue
18961895

18971896
# Save a label for this plot
18981897
trace_labels.append(f"From {sys.input_labels[i]}")
1898+
trace_types.append('impulse')
18991899

19001900
#
19011901
# Compute new X0 that contains the impulse
@@ -1935,7 +1935,7 @@ def impulse_response(sys, T=None, input=None, output=None, T_num=None,
19351935
response.time, yout, xout, uout, issiso=issiso,
19361936
output_labels=output_labels, input_labels=input_labels,
19371937
state_labels=sys.state_labels, trace_labels=trace_labels,
1938-
title="Impulse response for " + sys.name,
1938+
trace_types=trace_types, title="Impulse response for " + sys.name,
19391939
sysname=sys.name, plot_inputs=False, transpose=transpose,
19401940
return_x=return_x, squeeze=squeeze)
19411941

doc/plotting.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ following figure::
105105
U2 = np.vstack([np.cos(2*timepts), np.sin(timepts)])
106106
resp2 = ct.input_output_response(sys_mimo, timepts, U2)
107107

108-
ct.combine_traces(
108+
ct.combine_time_responses(
109109
[resp1, resp2], trace_labels=["Scenario #1", "Scenario #2"]).plot(
110110
transpose=True,
111111
title="I/O responses for 2x2 MIMO system, multiple traces "
@@ -114,9 +114,9 @@ following figure::
114114
.. image:: timeplot-mimo_ioresp-mt_tr.png
115115

116116
This figure also illustrates the ability to create "multi-trace" plots
117-
using the :func:`~control.combine_traces` function. The line properties
118-
that are used when combining signals and traces are set by the
119-
`input_props`, `output_props` and `trace_props` parameters for
117+
using the :func:`~control.combine_time_responses` function. The line
118+
properties that are used when combining signals and traces are set by
119+
the `input_props`, `output_props` and `trace_props` parameters for
120120
:func:`~control.time_response_plot`.
121121

122122
Additional customization is possible using the `input_props`,
@@ -138,5 +138,5 @@ Plotting functions
138138
:toctree: generated/
139139

140140
~control.time_response_plot
141-
~control.combine_traces
141+
~control.combine_time_responses
142142
~control.get_plot_axes

0 commit comments

Comments
 (0)