Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit71f4bc1

Browse files
committed
update shared axes processing in plot_time_response
1 parentecf6a38 commit71f4bc1

File tree

5 files changed

+85
-12
lines changed

5 files changed

+85
-12
lines changed

‎control/ctrlplot.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ def reset_rcParams():
334334

335335
def_process_ax_keyword(
336336
axs,shape=(1,1),rcParams=None,squeeze=False,clear_text=False,
337-
create_axes=True):
337+
create_axes=True,sharex=False,sharey=False):
338338
"""Process ax keyword to plotting commands.
339339
340340
This function processes the `ax` keyword to plotting commands. If no
@@ -364,10 +364,12 @@ def _process_ax_keyword(
364364
withplt.rc_context(rcParams):
365365
iflen(axs)!=0andcreate_axes:
366366
# Create a new figure
367-
fig,axs=plt.subplots(*shape,squeeze=False)
367+
fig,axs=plt.subplots(
368+
*shape,sharex=sharex,sharey=sharey,squeeze=False)
368369
elifcreate_axes:
369370
# Create new axes on (empty) figure
370-
axs=fig.subplots(*shape,squeeze=False)
371+
axs=fig.subplots(
372+
*shape,sharex=sharex,sharey=sharey,squeeze=False)
371373
else:
372374
# Create an empty array and let user create axes
373375
axs=np.full(shape,None)

‎control/freqplot.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,12 @@ def bode_plot(
198198
Determine whether and how axis limits are shared between the
199199
indicated variables. Can be set set to 'row' to share across all
200200
subplots in a row, 'col' to set across all subplots in a column, or
201-
`False` to allow independent limits.
201+
`False` to allow independent limits. Note: if `sharex` is given,
202+
it sets the value of `share_frequency`; if `sharey` is given, it
203+
sets the value of both `share_magnitude` and `share_phase`.
204+
Default values are 'row' for `share_magnitude` and `share_phase',
205+
'col', for `share_frequency`, and can be set using
206+
config.defaults['freqplot.share_<axis>'].
202207
show_legend : bool, optional
203208
Force legend to be shown if ``True`` or hidden if ``False``. If
204209
``None``, then show legend when there is more than one line on an
@@ -228,12 +233,12 @@ def bode_plot(
228233
229234
Notes
230235
-----
231-
1. Starting with python-control version 0.10, `bode_plot`returnsan
232-
array of linesinstead of magnitude, phase, and frequency. To
233-
recover the old behavior, call `bode_plot` with `plot=True`, which
234-
will force the legacy values (mag, phase, omega) to be returned
235-
(with a warning). To obtain just the frequency response of a system
236-
(or list of systems) without plotting, use the
236+
1. Starting with python-control version 0.10, `bode_plot`returnsa
237+
:class:`ControlPlot` objectinstead of magnitude, phase, and
238+
frequency. Torecover the old behavior, call `bode_plot` with
239+
`plot=True`, whichwill force the legacy values (mag, phase, omega)
240+
to be returned(with a warning). To obtain just the frequency
241+
response of a system(or list of systems) without plotting, use the
237242
:func:`~control.frequency_response` command.
238243
239244
2. If a discrete time model is given, the frequency response is plotted
@@ -583,7 +588,7 @@ def bode_plot(
583588
# axes are available and no updates should be made.
584589
#
585590

586-
# Utility function to turnoff sharing
591+
# Utility function to turnon sharing
587592
def_share_axes(ref,share_map,axis):
588593
ref_ax=ax_array[ref]
589594
forindexinnp.nditer(share_map,flags=["refs_ok"]):

‎control/tests/ctrlplot_test.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# RMM, 27 Jun 2024
33

44
importinspect
5+
importitertools
56
importwarnings
67

78
importmatplotlib.pyplotasplt
@@ -577,6 +578,45 @@ def test_plot_title_processing(resp_fcn, plot_fcn):
577578
assert"title : str, optional"inplot_fcn.__doc__
578579

579580

581+
@pytest.mark.parametrize("plot_fcn",multiaxes_plot_fcns)
582+
@pytest.mark.usefixtures('mplcleanup')
583+
deftest_tickmark_label_processing(plot_fcn):
584+
# Generate the response that we will use for plotting
585+
top_row,bot_row=0,-1
586+
matchplot_fcn:
587+
casect.bode_plot:
588+
resp=ct.frequency_response(ct.rss(4,2,2))
589+
top_row=1
590+
casect.time_response_plot:
591+
resp=ct.step_response(ct.rss(4,2,2))
592+
casect.gangof4_plot:
593+
resp=ct.gangof4_response(ct.rss(4,1,1),ct.rss(3,1,1))
594+
case _:
595+
pytest.fail("unknown plot_fcn")
596+
597+
# Turn off axis sharing => all axes have ticklabels
598+
cplt=resp.plot(sharex=False,sharey=False)
599+
fori,jinitertools.product(
600+
range(cplt.axes.shape[0]),range(cplt.axes.shape[1])):
601+
assertlen(cplt.axes[i,j].get_xticklabels())>0
602+
assertlen(cplt.axes[i,j].get_yticklabels())>0
603+
plt.clf()
604+
605+
# Turn on axis sharing => only outer axes have ticklabels
606+
cplt=resp.plot(sharex=True,sharey=True)
607+
fori,jinitertools.product(
608+
range(cplt.axes.shape[0]),range(cplt.axes.shape[1])):
609+
ifi<cplt.axes.shape[0]-1:
610+
assertlen(cplt.axes[i,j].get_xticklabels())==0
611+
else:
612+
assertlen(cplt.axes[i,j].get_xticklabels())>0
613+
614+
ifj>0:
615+
assertlen(cplt.axes[i,j].get_yticklabels())==0
616+
else:
617+
assertlen(cplt.axes[i,j].get_yticklabels())>0
618+
619+
580620
@pytest.mark.parametrize("resp_fcn, plot_fcn",resp_plot_fcns)
581621
@pytest.mark.usefixtures('mplcleanup','editsdefaults')
582622
deftest_rcParams(resp_fcn,plot_fcn):

‎control/timeplot.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
{'color':c}forcin [
3333
'tab:red','tab:purple','tab:brown','tab:olive','tab:cyan']],
3434
'timeplot.time_label':"Time [s]",
35+
'timeplot.sharex':'col',
36+
'timeplot.sharey':False,
3537
}
3638

3739

@@ -66,6 +68,14 @@ def time_response_plot(
6668
overlay_signals : bool, optional
6769
If set to True, combine all input and output signals onto a single
6870
plot (for each).
71+
sharex, sharey : str or bool, optional
72+
Determine whether and how x- and y-axis limits are shared between
73+
subplots. Can be set set to 'row' to share across all subplots in
74+
a row, 'col' to set across all subplots in a column, 'all' to share
75+
across all subplots, or `False` to allow independent limits.
76+
Default values are `False` for `sharex' and 'col' for `sharey`, and
77+
can be set using config.defaults['timeplot.sharex'] and
78+
config.defaults['timeplot.sharey'].
6979
transpose : bool, optional
7080
If transpose is False (default), signals are plotted from top to
7181
bottom, starting with outputs (if plotted) and then inputs.
@@ -176,6 +186,8 @@ def time_response_plot(
176186
#
177187
# Set up defaults
178188
ax_user=ax
189+
sharex=config._get_param('timeplot','sharex',kwargs,pop=True)
190+
sharey=config._get_param('timeplot','sharey',kwargs,pop=True)
179191
time_label=config._get_param(
180192
'timeplot','time_label',kwargs,_timeplot_defaults,pop=True)
181193
rcParams=config._get_param('ctrlplot','rcParams',kwargs,pop=True)
@@ -289,7 +301,8 @@ def time_response_plot(
289301
nrows,ncols=ncols,nrows
290302

291303
# See if we can use the current figure axes
292-
fig,ax_array=_process_ax_keyword(ax, (nrows,ncols),rcParams=rcParams)
304+
fig,ax_array=_process_ax_keyword(
305+
ax, (nrows,ncols),rcParams=rcParams,sharex=sharex,sharey=sharey)
293306
legend_loc,legend_map,show_legend=_process_legend_keywords(
294307
kwargs, (nrows,ncols),'center right')
295308

‎doc/plotting.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,19 @@ various ways. The following general rules apply:
536536
The default values for style parameters for control plots can be restored
537537
using:func:`~control.reset_rcParams`.
538538

539+
* For multi-input, multi-output time and frequency domain plots, the
540+
`sharex` and `sharey` keyword arguments can be used to determine whether
541+
and how axis limits are shared between the individual subplots. Setting
542+
the keyword to 'row' will share the axes limits across all subplots in a
543+
row, 'col' will share across all subplots in a column, 'all' will share
544+
across all subplots in the figure, and `False` will allow independent
545+
limits for each subplot.
546+
547+
For Bode plots, the `share_magnitude` and `share_phase` keyword arguments
548+
can be used to independently control axis limit sharing for the magnitude
549+
and phase portions of the plot, and `share_frequency` can be used instead
550+
of `sharex`.
551+
539552
* The ``title`` keyword can be used to override the automatic creation of
540553
the plot title. The default title is a string of the form "<Type> plot
541554
for <syslist>" where <syslist> is a list of the sys names contained in

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp