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

Commitde5ea5a

Browse files
committed
refactoring of nichols into response/plot + updated unit tests, examples
1 parent3496141 commitde5ea5a

File tree

9 files changed

+153
-161
lines changed

9 files changed

+153
-161
lines changed

‎LICENSE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
Copyright (c) 2009-2016 by California Institute of Technology
2+
Copyright (c) 2016-2023 by python-control developers
23
All rights reserved.
34

45
Redistribution and use in source and binary forms, with or without

‎control/frdata.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,12 +667,15 @@ def plot(self, plot_type=None, *args, **kwargs):
667667
668668
"""
669669
from .freqplotimportbode_plot,singular_values_plot
670+
from .nicholsimportnichols_plot
670671

671672
ifplot_typeisNone:
672673
plot_type=self.plot_type
673674

674675
ifplot_type=='bode':
675676
returnbode_plot(self,*args,**kwargs)
677+
elifplot_type=='nichols':
678+
returnnichols_plot(self,*args,**kwargs)
676679
elifplot_type=='svplot':
677680
returnsingular_values_plot(self,*args,**kwargs)
678681
else:

‎control/freqplot.py

Lines changed: 41 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,21 @@
11
# freqplot.py - frequency domain plots for control systems
22
#
3-
#Author: Richard M. Murray
3+
#Initial author: Richard M. Murray
44
# Date: 24 May 09
55
#
6-
# Functionality to add
7-
# [ ] Get rid of this long header (need some common, documented convention)
8-
# [x] Add mechanisms for storing/plotting margins? (currently forces FRD)
6+
# This file contains some standard control system plots: Bode plots,
7+
# Nyquist plots and other frequency response plots. The code for Nichols
8+
# charts is in nichols.py. The code for pole-zero diagrams is in pzmap.py
9+
# and rlocus.py.
10+
#
11+
# Functionality to add/check (Jul 2023, working list)
912
# [?] Allow line colors/styles to be set in plot() command (also time plots)
10-
# [x] Allow bode or nyquist style plots from plot()
11-
# [i] Allow nyquist_response() to generate the response curve (?)
12-
# [i] Allow MIMO frequency plots (w/ mag/phase subplots a la MATLAB)
13-
# [i] Update sisotool to use ax=
14-
# [i] Create __main__ in freqplot_test to view results (a la timeplot_test)
1513
# [ ] Get sisotool working in iPython and document how to make it work
16-
# [i] Allow share_magnitude, share_phase, share_frequency keywords for units
17-
# [i] Re-implement including of gain/phase margin in the title (?)
18-
# [i] Change gangof4 to use bode_plot(plot_phase=False) w/ proper labels
1914
# [ ] Allow use of subplot labels instead of output/input subtitles
20-
# [i] Add line labels to gangof4 [done by via bode_plot()]
2115
# [i] Allow frequency range to be overridden in bode_plot
2216
# [i] Unit tests for discrete time systems with different sample times
23-
# [c] Check examples/bode-and-nyquist-plots.ipynb for differences
2417
# [ ] Add unit tests for ct.config.defaults['freqplot_number_of_samples']
2518

26-
#
27-
# This file contains some standard control system plots: Bode plots,
28-
# Nyquist plots and other frequency response plots. The code for Nichols
29-
# charts is in nichols.py. The code for pole-zero diagrams is in pzmap.py
30-
# and rlocus.py.
31-
#
32-
# Copyright (c) 2010 by California Institute of Technology
33-
# All rights reserved.
34-
#
35-
# Redistribution and use in source and binary forms, with or without
36-
# modification, are permitted provided that the following conditions
37-
# are met:
38-
#
39-
# 1. Redistributions of source code must retain the above copyright
40-
# notice, this list of conditions and the following disclaimer.
41-
#
42-
# 2. Redistributions in binary form must reproduce the above copyright
43-
# notice, this list of conditions and the following disclaimer in the
44-
# documentation and/or other materials provided with the distribution.
45-
#
46-
# 3. Neither the name of the California Institute of Technology nor
47-
# the names of its contributors may be used to endorse or promote
48-
# products derived from this software without specific prior
49-
# written permission.
50-
#
51-
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
52-
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
53-
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
54-
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CALTECH
55-
# OR THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
56-
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
57-
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
58-
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
59-
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
60-
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
61-
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62-
# SUCH DAMAGE.
63-
#
64-
6519
importnumpyasnp
6620
importmatplotlibasmpl
6721
importmatplotlib.pyplotasplt
@@ -128,15 +82,12 @@ def plot(self, *args, plot_type=None, **kwargs):
12882
ifplot_typeisnotNoneandresponse.plot_type!=plot_type:
12983
raiseTypeError(
13084
"inconsistent plot_types in data; set plot_type "
131-
"to 'bode' or 'svplot'")
85+
"to 'bode', 'nichols', or 'svplot'")
13286
plot_type=response.plot_type
13387

134-
ifplot_type=='bode':
135-
returnbode_plot(self,*args,**kwargs)
136-
elifplot_type=='svplot':
137-
returnsingular_values_plot(self,*args,**kwargs)
138-
else:
139-
raiseValueError(f"unknown plot type '{plot_type}'")
88+
# Use FRD plot method, which can handle lists via plot functions
89+
returnFrequencyResponseData.plot(
90+
self,plot_type=plot_type,*args,**kwargs)
14091

14192
#
14293
# Bode plot
@@ -1936,23 +1887,7 @@ def _parse_linestyle(style_name, allow_false=False):
19361887
ax.grid(color="lightgray")
19371888

19381889
# List of systems that are included in this plot
1939-
labels,lines= [], []
1940-
last_color,counter=None,0# label unknown systems
1941-
fori,lineinenumerate(ax.get_lines()):
1942-
label=line.get_label()
1943-
iflabel.startswith("Unknown"):
1944-
label=f"Unknown-{counter}"
1945-
iflast_colorisNone:
1946-
last_color=line.get_color()
1947-
eliflast_color!=line.get_color():
1948-
counter+=1
1949-
last_color=line.get_color()
1950-
eliflabel[0]=='_':
1951-
continue
1952-
1953-
iflabelnotinlabels:
1954-
lines.append(line)
1955-
labels.append(label)
1890+
lines,labels=_get_line_labels(ax)
19561891

19571892
# Add legend if there is more than one system plotted
19581893
iflen(labels)>1:
@@ -2279,6 +2214,9 @@ def singular_values_plot(
22792214
(legacy) If given, `singular_values_plot` returns the legacy return
22802215
values of magnitude, phase, and frequency. If False, just return
22812216
the values with no plot.
2217+
legend_loc : str, optional
2218+
For plots with multiple lines, a legend will be included in the
2219+
given location. Default is 'center right'. Use False to supress.
22822220
**kwargs : :func:`matplotlib.pyplot.plot` keyword properties, optional
22832221
Additional keywords passed to `matplotlib` to specify line properties.
22842222
@@ -2400,8 +2338,8 @@ def singular_values_plot(
24002338
ifdB:
24012339
withplt.rc_context(freqplot_rcParams):
24022340
out[idx_sys]=ax_sigma.semilogx(
2403-
omega_plot,20*np.log10(sigma_plot),color=color,
2404-
label=sysname,*fmt,**kwargs)
2341+
omega_plot,20*np.log10(sigma_plot),*fmt,color=color,
2342+
label=sysname,**kwargs)
24052343
else:
24062344
withplt.rc_context(freqplot_rcParams):
24072345
out[idx_sys]=ax_sigma.loglog(
@@ -2422,26 +2360,10 @@ def singular_values_plot(
24222360
ax_sigma.set_xlabel("Frequency [Hz]"ifHzelse"Frequency [rad/sec]")
24232361

24242362
# List of systems that are included in this plot
2425-
labels,lines= [], []
2426-
last_color,counter=None,0# label unknown systems
2427-
fori,lineinenumerate(ax_sigma.get_lines()):
2428-
label=line.get_label()
2429-
iflabel.startswith("Unknown"):
2430-
label=f"Unknown-{counter}"
2431-
iflast_colorisNone:
2432-
last_color=line.get_color()
2433-
eliflast_color!=line.get_color():
2434-
counter+=1
2435-
last_color=line.get_color()
2436-
eliflabel[0]=='_':
2437-
continue
2438-
2439-
iflabelnotinlabels:
2440-
lines.append(line)
2441-
labels.append(label)
2363+
lines,labels=_get_line_labels(ax_sigma)
24422364

24432365
# Add legend if there is more than one system plotted
2444-
iflen(labels)>1:
2366+
iflen(labels)>1andlegend_locisnotFalse:
24452367
withplt.rc_context(freqplot_rcParams):
24462368
ax_sigma.legend(lines,labels,loc=legend_loc)
24472369

@@ -2649,6 +2571,28 @@ def _default_frequency_range(syslist, Hz=None, number_of_samples=None,
26492571
returnomega
26502572

26512573

2574+
# Get labels for all lines in an axes
2575+
def_get_line_labels(ax,use_color=True):
2576+
labels,lines= [], []
2577+
last_color,counter=None,0# label unknown systems
2578+
fori,lineinenumerate(ax.get_lines()):
2579+
label=line.get_label()
2580+
ifuse_colorandlabel.startswith("Unknown"):
2581+
label=f"Unknown-{counter}"
2582+
iflast_colorisNone:
2583+
last_color=line.get_color()
2584+
eliflast_color!=line.get_color():
2585+
counter+=1
2586+
last_color=line.get_color()
2587+
eliflabel[0]=='_':
2588+
continue
2589+
2590+
iflabelnotinlabels:
2591+
lines.append(line)
2592+
labels.append(label)
2593+
2594+
returnlines,labels
2595+
26522596
#
26532597
# Utility functions to create nice looking labels (KLD 5/23/11)
26542598
#

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp