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

Commit3b19ae9

Browse files
authored
Fix plot issues (#382)
* fix sgrid, zgrid to use existing axes if they exist + PEP8 cleanup* change plot and print_gain keywords to lower case, with deprecation warning + fix bugs in gangof4 using dB + PEP8, docstring cleanup* remove conversion to state space that was giving spurious zero at infinity* change plot and print_gain keywords to lower case, with deprecation warning* PEP8 cleanup* use Hz=False for MATLAB + docstring corrections* labelFreq -> label_freq in nyquist_plot() w/ deprecation warning + remove extraneous docstring text
1 parenta09d059 commit3b19ae9

File tree

13 files changed

+203
-129
lines changed

13 files changed

+203
-129
lines changed

‎control/config.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,11 @@ def use_matlab_defaults():
114114
115115
The following conventions are used:
116116
* Bode plots plot gain in dB, phase in degrees, frequency in
117-
Hertz, with grids
117+
rad/sec, with grids
118118
* State space class and functions use Numpy matrix objects
119119
120120
"""
121-
set_defaults('bode',dB=True,deg=True,Hz=True,grid=True)
121+
set_defaults('bode',dB=True,deg=True,Hz=False,grid=True)
122122
set_defaults('statesp',use_numpy_matrix=True)
123123

124124

@@ -128,7 +128,7 @@ def use_fbs_defaults():
128128
129129
The following conventions are used:
130130
* Bode plots plot gain in powers of ten, phase in degrees,
131-
frequency inHertz, no grid
131+
frequency inrad/sec, no grid
132132
133133
"""
134134
set_defaults('bode',dB=False,deg=True,Hz=False,grid=False)

‎control/freqplot.py

Lines changed: 76 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080

8181

8282
defbode_plot(syslist,omega=None,
83-
Plot=True,omega_limits=None,omega_num=None,
83+
plot=True,omega_limits=None,omega_num=None,
8484
margins=None,*args,**kwargs):
8585
"""Bode plot for a system
8686
@@ -100,7 +100,7 @@ def bode_plot(syslist, omega=None,
100100
deg : bool
101101
If True, plot phase in degrees (else radians). Default value (True)
102102
config.defaults['bode.deg']
103-
Plot : bool
103+
plot : bool
104104
If True (default), plot magnitude and phase
105105
omega_limits: tuple, list, ... of two values
106106
Limits of the to generate frequency vector.
@@ -110,9 +110,9 @@ def bode_plot(syslist, omega=None,
110110
config.defaults['freqplot.number_of_samples'].
111111
margins : bool
112112
If True, plot gain and phase margin.
113-
*args
114-
Additional arguments for:func:`matplotlib.plot` (color, linestyle, etc)
115-
**kwargs:
113+
*args : `matplotlib` plot positional properties, optional
114+
Additional arguments for `matplotlib` plots (color, linestyle, etc)
115+
**kwargs : `matplotlib` plot keyword properties, optional
116116
Additional keywords (passed to `matplotlib`)
117117
118118
Returns
@@ -153,12 +153,20 @@ def bode_plot(syslist, omega=None,
153153
# Make a copy of the kwargs dictonary since we will modify it
154154
kwargs=dict(kwargs)
155155

156+
# Check to see if legacy 'Plot' keyword was used
157+
if'Plot'inkwargs:
158+
importwarnings
159+
warnings.warn("'Plot' keyword is deprecated in bode_plot; use 'plot'",
160+
FutureWarning)
161+
# Map 'Plot' keyword to 'plot' keyword
162+
plot=kwargs.pop('Plot')
163+
156164
# Get values for params (and pop from list to allow keyword use in plot)
157165
dB=config._get_param('bode','dB',kwargs,_bode_defaults,pop=True)
158166
deg=config._get_param('bode','deg',kwargs,_bode_defaults,pop=True)
159167
Hz=config._get_param('bode','Hz',kwargs,_bode_defaults,pop=True)
160168
grid=config._get_param('bode','grid',kwargs,_bode_defaults,pop=True)
161-
Plot=config._get_param('bode','grid',Plot,True)
169+
plot=config._get_param('bode','grid',plot,True)
162170
margins=config._get_param('bode','margins',margins,False)
163171

164172
# If argument was a singleton, turn it into a list
@@ -211,7 +219,7 @@ def bode_plot(syslist, omega=None,
211219
# Get the dimensions of the current axis, which we will divide up
212220
# TODO: Not current implemented; just use subplot for now
213221

214-
ifPlot:
222+
ifplot:
215223
nyquistfrq_plot=None
216224
ifHz:
217225
omega_plot=omega_sys/ (2.*math.pi)
@@ -429,12 +437,13 @@ def gen_zero_centered_series(val_min, val_max, period):
429437
else:
430438
returnmags,phases,omegas
431439

440+
432441
#
433442
# Nyquist plot
434443
#
435444

436-
defnyquist_plot(syslist,omega=None,Plot=True,
437-
labelFreq=0,arrowhead_length=0.1,arrowhead_width=0.1,
445+
defnyquist_plot(syslist,omega=None,plot=True,label_freq=0,
446+
arrowhead_length=0.1,arrowhead_width=0.1,
438447
color=None,*args,**kwargs):
439448
"""
440449
Nyquist plot for a system
@@ -451,13 +460,13 @@ def nyquist_plot(syslist, omega=None, Plot=True,
451460
If True, plot magnitude
452461
color : string
453462
Used to specify the color of the plot
454-
labelFreq : int
463+
label_freq : int
455464
Label every nth frequency on the plot
456465
arrowhead_width : arrow head width
457466
arrowhead_length : arrow head length
458-
*args
459-
Additional arguments for:func:`matplotlib.plot` (color, linestyle, etc)
460-
**kwargs:
467+
*args : `matplotlib` plot positional properties, optional
468+
Additional arguments for `matplotlib` plots (color, linestyle, etc)
469+
**kwargs : `matplotlib` plot keyword properties, optional
461470
Additional keywords (passed to `matplotlib`)
462471
463472
Returns
@@ -475,6 +484,22 @@ def nyquist_plot(syslist, omega=None, Plot=True,
475484
>>> real, imag, freq = nyquist_plot(sys)
476485
477486
"""
487+
# Check to see if legacy 'Plot' keyword was used
488+
if'Plot'inkwargs:
489+
importwarnings
490+
warnings.warn("'Plot' keyword is deprecated in nyquist_plot; "
491+
"use 'plot'",FutureWarning)
492+
# Map 'Plot' keyword to 'plot' keyword
493+
plot=kwargs.pop('Plot')
494+
495+
# Check to see if legacy 'labelFreq' keyword was used
496+
if'labelFreq'inkwargs:
497+
importwarnings
498+
warnings.warn("'labelFreq' keyword is deprecated in nyquist_plot; "
499+
"use 'label_freq'",FutureWarning)
500+
# Map 'labelFreq' keyword to 'label_freq' keyword
501+
label_freq=kwargs.pop('labelFreq')
502+
478503
# If argument was a singleton, turn it into a list
479504
ifnotgetattr(syslist,'__iter__',False):
480505
syslist= (syslist,)
@@ -507,7 +532,7 @@ def nyquist_plot(syslist, omega=None, Plot=True,
507532
x=sp.multiply(mag,sp.cos(phase))
508533
y=sp.multiply(mag,sp.sin(phase))
509534

510-
ifPlot:
535+
ifplot:
511536
# Plot the primary curve and mirror image
512537
p=plt.plot(x,y,'-',color=color,*args,**kwargs)
513538
c=p[0].get_color()
@@ -527,8 +552,8 @@ def nyquist_plot(syslist, omega=None, Plot=True,
527552
plt.plot([-1], [0],'r+')
528553

529554
# Label the frequencies of the points
530-
iflabelFreq:
531-
ind=slice(None,None,labelFreq)
555+
iflabel_freq:
556+
ind=slice(None,None,label_freq)
532557
forxpt,ypt,omegaptinzip(x[ind],y[ind],omega[ind]):
533558
# Convert to Hz
534559
f=omegapt/ (2*sp.pi)
@@ -550,14 +575,15 @@ def nyquist_plot(syslist, omega=None, Plot=True,
550575
str(int(np.round(f/1000**pow1000,0)))+' '+
551576
prefix+'Hz')
552577

553-
ifPlot:
578+
ifplot:
554579
ax=plt.gca()
555580
ax.set_xlabel("Real axis")
556581
ax.set_ylabel("Imaginary axis")
557582
ax.grid(color="lightgray")
558583

559584
returnx,y,omega
560585

586+
561587
#
562588
# Gang of Four plot
563589
#
@@ -575,6 +601,8 @@ def gangof4_plot(P, C, omega=None, **kwargs):
575601
Linear input/output systems (process and control)
576602
omega : array
577603
Range of frequencies (list or bounds) in rad/sec
604+
**kwargs : `matplotlib` plot keyword properties, optional
605+
Additional keywords (passed to `matplotlib`)
578606
579607
Returns
580608
-------
@@ -590,16 +618,16 @@ def gangof4_plot(P, C, omega=None, **kwargs):
590618
Hz=config._get_param('bode','Hz',kwargs,_bode_defaults,pop=True)
591619
grid=config._get_param('bode','grid',kwargs,_bode_defaults,pop=True)
592620

593-
# Select a default range if none is provided
594-
# TODO: This needs to be made more intelligent
595-
ifomegaisNone:
596-
omega=default_frequency_range((P,C))
597-
598621
# Compute the senstivity functions
599622
L=P*C
600623
S=feedback(1,L)
601624
T=L*S
602625

626+
# Select a default range if none is provided
627+
# TODO: This needs to be made more intelligent
628+
ifomegaisNone:
629+
omega=default_frequency_range((P,C,S))
630+
603631
# Set up the axes with labels so that multiple calls to
604632
# gangof4_plot will superimpose the data. See details in bode_plot.
605633
plot_axes= {'t':None,'s':None,'ps':None,'cs':None}
@@ -628,36 +656,49 @@ def gangof4_plot(P, C, omega=None, **kwargs):
628656
# TODO: Need to add in the mag = 1 lines
629657
mag_tmp,phase_tmp,omega=S.freqresp(omega)
630658
mag=np.squeeze(mag_tmp)
631-
plot_axes['s'].loglog(omega_plot,20*np.log10(mag)ifdBelsemag)
632-
plot_axes['s'].set_ylabel("$|S|$")
659+
ifdB:
660+
plot_axes['s'].semilogx(omega_plot,20*np.log10(mag),**kwargs)
661+
else:
662+
plot_axes['s'].loglog(omega_plot,mag,**kwargs)
663+
plot_axes['s'].set_ylabel("$|S|$"+" (dB)"ifdBelse"")
633664
plot_axes['s'].tick_params(labelbottom=False)
634665
plot_axes['s'].grid(grid,which='both')
635666

636667
mag_tmp,phase_tmp,omega= (P*S).freqresp(omega)
637668
mag=np.squeeze(mag_tmp)
638-
plot_axes['ps'].loglog(omega_plot,20*np.log10(mag)ifdBelsemag)
669+
ifdB:
670+
plot_axes['ps'].semilogx(omega_plot,20*np.log10(mag),**kwargs)
671+
else:
672+
plot_axes['ps'].loglog(omega_plot,mag,**kwargs)
639673
plot_axes['ps'].tick_params(labelbottom=False)
640-
plot_axes['ps'].set_ylabel("$|PS|$")
674+
plot_axes['ps'].set_ylabel("$|PS|$"+" (dB)"ifdBelse"")
641675
plot_axes['ps'].grid(grid,which='both')
642676

643677
mag_tmp,phase_tmp,omega= (C*S).freqresp(omega)
644678
mag=np.squeeze(mag_tmp)
645-
plot_axes['cs'].loglog(omega_plot,20*np.log10(mag)ifdBelsemag)
679+
ifdB:
680+
plot_axes['cs'].semilogx(omega_plot,20*np.log10(mag),**kwargs)
681+
else:
682+
plot_axes['cs'].loglog(omega_plot,mag,**kwargs)
646683
plot_axes['cs'].set_xlabel(
647684
"Frequency (Hz)"ifHzelse"Frequency (rad/sec)")
648-
plot_axes['cs'].set_ylabel("$|CS|$")
685+
plot_axes['cs'].set_ylabel("$|CS|$"+" (dB)"ifdBelse"")
649686
plot_axes['cs'].grid(grid,which='both')
650687

651688
mag_tmp,phase_tmp,omega=T.freqresp(omega)
652689
mag=np.squeeze(mag_tmp)
653-
plot_axes['t'].loglog(omega_plot,20*np.log10(mag)ifdBelsemag)
690+
ifdB:
691+
plot_axes['t'].semilogx(omega_plot,20*np.log10(mag),**kwargs)
692+
else:
693+
plot_axes['t'].loglog(omega_plot,mag,**kwargs)
654694
plot_axes['t'].set_xlabel(
655695
"Frequency (Hz)"ifHzelse"Frequency (rad/sec)")
656-
plot_axes['t'].set_ylabel("$|T|$")
696+
plot_axes['t'].set_ylabel("$|T|$"+" (dB)"ifdBelse"")
657697
plot_axes['t'].grid(grid,which='both')
658698

659699
plt.tight_layout()
660700

701+
661702
#
662703
# Utility functions
663704
#
@@ -754,7 +795,7 @@ def default_frequency_range(syslist, Hz=None, number_of_samples=None,
754795
# TODO
755796
raiseNotImplementedError(
756797
"type of system in not implemented now")
757-
except:
798+
exceptNotImplementedError:
758799
pass
759800

760801
# Make sure there is at least one point in the range
@@ -787,15 +828,17 @@ def default_frequency_range(syslist, Hz=None, number_of_samples=None,
787828
omega=sp.logspace(lsp_min,lsp_max,endpoint=True)
788829
returnomega
789830

831+
790832
#
791-
#KLD 5/23/11: Twofunctions to create nice looking labels
833+
#Utilityfunctions to create nice looking labels (KLD 5/23/11)
792834
#
793835

794836
defget_pow1000(num):
795837
"""Determine exponent for which significand of a number is within the
796838
range [1, 1000).
797839
"""
798-
# Based on algorithm from http://www.mail-archive.com/matplotlib-users@lists.sourceforge.net/msg14433.html, accessed 2010/11/7
840+
# Based on algorithm from http://www.mail-archive.com/
841+
# matplotlib-users@lists.sourceforge.net/msg14433.html, accessed 2010/11/7
799842
# by Jason Heeris 2009/11/18
800843
fromdecimalimportDecimal
801844
frommathimportfloor

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp