8000 fix shape of output for time_reesponse_plot() · python-control/python-control@e098625 · GitHub
[go: up one dir, main page]

Skip to content

Commit e098625< 10000 /h1>

Browse files
committed
fix shape of output for time_reesponse_plot()
1 parent 6b2d555 commit e098625

File tree

2 files changed

+43
-41
lines changed

2 files changed

+43
-41
lines changed

control/tests/timeplot_test.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -135,21 +135,23 @@ def test_response_plots(
135135

136136
out = response.plot(**kwargs)
137137

138+
# Make sure all of the outputs are of the right type
139+
nlines_plotted = 0
140+
for ax_lines in np.nditer(out, flags=["refs_ok"]):
141+
for line in ax_lines.item():
142+
assert isinstance(line, mpl.lines.Line2D)
143+
nlines_plotted += 1
144+
138145
# Make sure number of plots is correct
139146
if pltinp is None:
140147
if fcn in [ct.forced_response, ct.input_output_response]:
141148
pltinp = True
142149
else:
143150
pltinp = False
144151
ntraces = max(1, response.ntraces)
145-
nlines = (response.ninputs if pltinp else 0) * ntraces + \
152+
nlines_expected = (response.ninputs if pltinp else 0) * ntraces + \
146153
(response.noutputs if pltout else 0) * ntraces
147-
assert out.size == nlines
148-
149-
# Make sure all of the outputs are of the right type
150-
for ax_lines in np.nditer(out, flags=["refs_ok"]):
151-
for line in ax_lines.item():
152-
assert isinstance(line, mpl.lines.Line2D)
154+
assert nlines_plotted == nlines_expected
153155

154156
# Save the old axes to compare later
155157
old_axes = plt.gcf().get_axes()
@@ -326,17 +328,17 @@ def test_linestyles():
326328
output_props=[{'color': c} for c in ['blue', 'orange']],
327329
input_props=[{'color': c} for c in ['red', 'green']],
328330
trace_props=[{'linestyle': s} for s in ['-', '--']])
329-
return None
330-
# assert out.shape == (1, 1) # TODO: fix
331-
assert out[0,0].get_color() == 'blue' and lines[0].get_linestyle() == '-'
332-
assert out[0,1].get_color() == 'blue' and lines[0].get_linestyle() == '--'
333-
assert out[1,0].get_color() == 'orange' and lines[0].get_linestyle() == '-'
334-
assert out[1,1].get_color() == 'orange' and lines[0].get_linestyle() == '--'
335-
assert out[2,0].get_color() == 'red' and lines[0].get_linestyle() == '-'
336-
assert out[2,1].get_color() == 'red' and lines[0].get_linestyle() == '--'
337-
assert out[3,0].get_color() == 'green' and lines[0].get_linestyle() == '-'
338-
assert out[3,1].get_color() == 'green' and lines[0].get_linestyle() == '--'
339331

332+
assert out.shape == (1, 1)
333+
lines = out[0, 0]
334+
assert lines[0].get_color() == 'blue' and lines[0].get_linestyle() == '-'
335+
assert lines[1].get_color() == 'orange' and lines[1].get_linestyle() == '-'
336+
assert lines[2].get_color() == 'red' and lines[2].get_linestyle() == '-'
337+
assert lines[3].get_color() == 'green' and lines[3].get_linestyle() == '-'
338+
assert lines[4].get_color() == 'blue' and lines[4].get_linestyle() == '--'
339+
assert lines[5].get_color() == 'orange' and lines[5].get_linestyle() == '--'
340+
assert lines[6].get_color() == 'red' and lines[6].get_linestyle() == '--'
341+
assert lines[7].get_color() == 'green' and lines[7].get_linestyle() == '--'
340342

341343
def test_relabel():
342344
sys1 = ct.rss(2, inputs='u', outputs='y')

control/timeplot.py

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ def time_response_plot(
4848
data, *fmt, ax=None, plot_inputs=None, plot_outputs=True,
4949
transpose=False, overlay_traces=False, overlay_signals=False,
5050
legend_map=None, legend_loc=None, add_initial_zero=True,
51-
input_props=None, output_props=None, trace_props=None,
5251
trace_labels=None, title=None, relabel=True, **kwargs):
5352
"""Plot the time response of an input/output system.
5453
@@ -162,19 +161,19 @@ def time_response_plot(
162161
time_label = config._get_param(
163162
'timeplot', 'time_label', kwargs, _timeplot_defaults, pop=True)
164163

165-
if input_props and len(fmt) > 0:
164+
if kwargs.get('input_props', None) and len(fmt) > 0:
166165
warn("input_props ignored since fmt string was present")
167166
input_props = config._get_param(
168167
'timeplot', 'input_props', kwargs, _timeplot_defaults, pop=True)
169168
iprop_len = len(input_props)
170169

171-
if output_props and len(fmt) > 0:
170+
if kwargs.get('output_props', None) and len(fmt) > 0:
172171
warn("output_props ignored since fmt string was present")
173172
output_props = config._get_param(
174173
'timeplot', 'output_props', kwargs, _timeplot_defaults, pop=True)
175174
oprop_len = len(output_props)
176175

177-
if trace_props and len(fmt) > 0:
176+
if kwargs.get('trace_props', None) and len(fmt) > 0:
178177
warn("trace_props ignored since fmt string was present")
179178
trace_props = config._get_param(
180179
'timeplot', 'trace_props', kwargs, _timeplot_defaults, pop=True)
@@ -306,35 +305,33 @@ def time_response_plot(
306305
# Map inputs/outputs and traces to axes
307306
#
308307
# This set of code takes care of all of the various options for how to
309-
# plot the data. The arrays ax_outputs and ax_inputs are used to map
308+
# plot the data. The arrays output_map and input_map are used to map
310309
# the different signals that are plotted onto the axes created above.
311310
# This code is complicated because it has to handle lots of different
312311
# variations.
313312
#
314313

315314
# Create the map from trace, signal to axes, accounting for overlay_*
316-
ax_outputs = np.empty((noutputs, ntraces), dtype=object)
317-
ax_inputs = np.empty((ninputs, ntraces), dtype=object)
315+
output_map = np.empty((noutputs, ntraces), dtype=tuple)
316+
input_map = np.empty((ninputs, ntraces), dtype=tuple)
318317

319318
for i in range(noutputs):
320319
for j in range(ntraces):
321320
signal_index = i if not overlay_signals else 0
322321
trace_index = j if not overlay_traces else 0
323322
if transpose:
324-
ax_outputs[i, j] = \
325-
ax_array[trace_index, signal_index + ninput_axes]
323+
output_map[i, j] = (trace_index, signal_index + ninput_axes)
326324
else:
327-
ax_outputs[i, j] = ax_array[signal_index, trace_index]
325+
output_map[i, j] = (signal_index, trace_index)
328326

329327
for i in range(ninputs):
330328
for j in range(ntraces):
331329
signal_index = noutput_axes + (i if not overlay_signals else 0)
332330
trace_index = j if not overlay_traces else 0
333331
if transpose:
334-
ax_inputs[i, j] = \
335-
ax_array[trace_index, signal_index - noutput_axes]
332+
input_map[i, j] = (trace_index, signal_index - noutput_axes)
336333
else:
337-
ax_inputs[i, j] = ax_array[signal_index, trace_index]
334+
input_map[i, j] = (signal_index, trace_index)
338335

339336
#
340337
# Plot the data
@@ -361,7 +358,10 @@ def time_response_plot(
361358
inputs = data.u.reshape(data.ninputs, ntraces, -1)
362359

363360
# Create a list of lines for the output
364-
out = np.empty((noutputs + ninputs, ntraces), dtype=object)
361+
out = np.empty((nrows, ncols), dtype=object)
362+
for i in range(nrows):
363+
for j in range(ncols):
364+
out[i, j] = [] # unique list in each element
365365

366366
# Utility function for creating line label
367367
def _make_line_label(signal_index, signal_labels, trace_index):
@@ -402,7 +402,7 @@ def _make_line_label(signal_index, signal_labels, trace_index):
402402
else:
403403
line_props = kwargs
404404

405-
out[i, trace] = ax_outputs[i, trace].plot(
405+
out[output_map[i, trace]] += ax_array[output_map[i, trace]].plot(
406406
data.time, outputs[i][trace], *fmt, label=label, **line_props)
407407

408408
# Plot the input
@@ -425,7 +425,7 @@ def _make_line_label(signal_index, signal_labels, trace_index):
425425
else:
426426
line_props = kwargs
427427

428-
out[noutputs + i, trace] = ax_inputs[i, trace].plot(
428+
out[input_map[i, trace]] += ax_array[input_map[i, trace]].plot(
429429
x, y, *fmt, label=label, **line_props)
430430

431431
# Stop here if the user wants to control everything
@@ -457,23 +457,23 @@ def _make_line_label(signal_index, signal_labels, trace_index):
457457
if overlay_signals and plot_inputs:
458458
label = overlaid_title if overlaid else "Inputs"
459459
for trace in range(ntraces):
460-
ax_inputs[0, trace].set_ylabel(label)
460+
ax_array[input_map[0, trace]].set_ylabel(label)
461461
else:
462462
for i in range(ninputs):
463463
label = overlaid_title if overlaid else data.input_labels[i]
464464
for trace in range(ntraces):
465-
ax_inputs[i, trace].set_ylabel(label)
465+
ax_array[input_map[i, trace]].set_ylabel(label)
466466

467467
# Label the outputs
468468
if overlay_signals and plot_outputs:
469469
label = overlaid_title if overlaid else "Outputs"
470470
for trace in range(ntraces):
471-
ax_outputs[0, trace].set_ylabel(label)
471+
ax_array[output_map[0, trace]].set_ylabel(label)
472472
else:
473473
for i in range(noutputs):
474474
label = overlaid_title if overlaid else data.output_labels[i]
475475
for trace in range(ntraces):
476-
ax_outputs[i, trace].set_ylabel(label)
476+
ax_array[output_map[i, trace]].set_ylabel(label)
477477

478478
# Set the trace titles, if needed
479479
if ntraces > 1 and not overlay_traces:
@@ -507,20 +507,20 @@ def _make_line_label(signal_index, signal_labels, trace_index):
507507

508508
# Label the outputs
509509
if overlay_signals and plot_outputs:
510-
ax_outputs[0, 0].set_ylabel("Outputs")
510+
ax_array[output_map[0, 0]].set_ylabel("Outputs")
511511
else:
512512
for i in range(noutputs):
513-
ax_outputs[i, 0].set_ylabel(
513+
ax_array[output_map[i, 0]].set_ylabel(
514514
overlaid_title if overlaid else data.output_labels[i])
515515

516516
# Label the inputs
517517
if overlay_signals and plot_inputs:
518518
label = overlaid_title if overlaid else "Inputs"
519-
ax_inputs[0, 0].set_ylabel(label)
519+
ax_array[input_map[0, 0]].set_ylabel(label)
520520
else:
521521
for i in range(ninputs):
522522
label = overlaid_title if overlaid else data.input_labels[i]
523-
ax_inputs[i, 0].set_ylabel(label)
523+
ax_array[input_map[i, 0]].set_ylabel(label)
524524

525525
#
526526
# Create legends

0 commit comments

Comments
 (0)
0