Skip to content

Commit 5735395

Browse files
committed
fix(timeplot): accept response lists
Route TimeResponseList and plain lists of time responses through the existing TimeResponseList plotting path when calling the public time_response_plot function directly. This keeps response_list.plot() behavior unchanged while fixing the standalone function for list-returning simulation calls.
1 parent 146ccee commit 5735395

2 files changed

Lines changed: 37 additions & 1 deletion

File tree

control/tests/timeplot_test.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,24 @@ def test_list_responses(resp_fcn):
369369
assert cplt.lines[row, col][0].get_color() == 'tab:blue'
370370
assert cplt.lines[row, col][1].get_color() == 'tab:orange'
371371

372+
# Make sure the public plotting function also accepts response lists
373+
plt.figure()
374+
cplt = ct.time_response_plot(resp_combined)
375+
assert cplt.lines.shape == shape
376+
for row in range(2): # just look at the outputs
377+
for col in range(shape[1]):
378+
assert cplt.lines[row, col][0].get_color() == 'tab:blue'
379+
assert cplt.lines[row, col][1].get_color() == 'tab:orange'
380+
381+
# Plain Python lists of time responses should follow the same path
382+
plt.figure()
383+
cplt = ct.time_response_plot([resp1, resp2])
384+
assert cplt.lines.shape == shape
385+
for row in range(2): # just look at the outputs
386+
for col in range(shape[1]):
387+
assert cplt.lines[row, col][0].get_color() == 'tab:blue'
388+
assert cplt.lines[row, col][1].get_color() == 'tab:orange'
389+
372390

373391
@pytest.mark.slycot
374392
@pytest.mark.usefixtures('mplcleanup')

control/timeplot.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def time_response_plot(
5252
5353
Parameters
5454
----------
55-
data : `TimeResponseData`
55+
data : `TimeResponseData` or list of `TimeResponseData`
5656
Data to be plotted.
5757
plot_inputs : bool or str, optional
5858
Sets how and where to plot the inputs:
@@ -176,6 +176,24 @@ def time_response_plot(
176176
"""
177177
from .ctrlplot import _process_ax_keyword, _process_line_labels
178178

179+
# If given a list of time responses, plot them sequentially on the same
180+
# axes using the same path as TimeResponseList.plot().
181+
if isinstance(data, list):
182+
if len(data) == 0:
183+
raise ValueError("response list must contain at least one response")
184+
185+
from .timeresp import TimeResponseList
186+
187+
list_kwargs = dict(
188+
ax=ax, plot_inputs=plot_inputs, plot_outputs=plot_outputs,
189+
transpose=transpose, overlay_traces=overlay_traces,
190+
overlay_signals=overlay_signals, add_initial_zero=add_initial_zero,
191+
trace_labels=trace_labels, title=title, relabel=relabel)
192+
if label is not None:
193+
list_kwargs['label'] = label
194+
195+
return TimeResponseList(data).plot(*fmt, **list_kwargs, **kwargs)
196+
179197
#
180198
# Process keywords and set defaults
181199
#

0 commit comments

Comments
 (0)