Skip to content

Commit aef3b06

Browse files
committed
tweak max_curve_magnitude + add start point
1 parent 3d3a559 commit aef3b06

File tree

2 files changed

+49
-12
lines changed

2 files changed

+49
-12
lines changed

control/freqplot.py

+42-12
Original file line numberDiff line numberDiff line change
@@ -519,15 +519,17 @@ def gen_zero_centered_series(val_min, val_max, period):
519519

520520
# Default values for module parameter variables
521521
_nyquist_defaults = {
522-
'nyquist.primary_style': ['-', '-.'], # style for primary curve
523-
'nyquist.mirror_style': ['--', ':'], # style for mirror curve
524-
'nyquist.arrows': 2,
525-
'nyquist.arrow_size': 8,
526-
'nyquist.indent_radius': 1e-6, # indentation radius
522+
'nyquist.primary_style': ['-', '-.'], # style for primary curve
523+
'nyquist.mirror_style': ['--', ':'], # style for mirror curve
524+
'nyquist.arrows': 2, # number of arrors around curve
525+
'nyquist.arrow_size': 8, # pixel size for arrows
526+
'nyquist.indent_radius': 1e-4, # indentation radius
527527
'nyquist.indent_direction': 'right', # indentation direction
528528
'nyquist.indent_points': 50, # number of points to insert
529-
'nyquist.max_curve_magnitude': 20,
530-
'nyquist.max_curve_offset': 0.02, # percent offset of curves
529+
'nyquist.max_curve_magnitude': 20, # clip large values
530+
'nyquist.max_curve_offset': 0.02, # offset of primary/mirror
531+
'nyquist.start_marker': 'o', # marker at start of curve
532+
'nyquist.start_marker_size': 4, # size of the maker
531533
}
532534

533535

@@ -618,8 +620,9 @@ def nyquist_plot(syslist, omega=None, plot=True, omega_limits=None,
618620
are at or near the imaginary axis.
619621
620622
indent_radius : float, optional
621-
Amount to indent the Nyquist contour around poles that are at or near
622-
the imaginary axis.
623+
Amount to indent the Nyquist contour around poles on or near the
624+
imaginary axis. Portions of the Nyquist plot corresponding to indented
625+
portions of the contour are plotted using a different line style.
623626
624627
max_curve_magnitude : float, optional
625628
Restrict the maximum magnitude of the Nyquist plot to this value.
@@ -638,13 +641,22 @@ def nyquist_plot(syslist, omega=None, plot=True, omega_limits=None,
638641
`False` then omit completely. Default linestyle (['--', '-.']) is
639642
determined by config.defaults['nyquist.mirror_style'].
640643
641-
primary_style : [str, str]
644+
primary_style : [str, str], optional
642645
Linestyles for primary image of the Nyquist curve. The first element
643646
is used for unscaled portions of the Nyquist curve, the second
644647
element is used for scaled portions that are scaled (using
645648
max_curve_magnitude). Default linestyle (['-', ':']) is determined by
646649
config.defaults['nyquist.mirror_style'].
647650
651+
start_marker : str, optional
652+
Matplotlib marker to use to mark the starting point of the Nyquist
653+
plot. Defaults value is 'o' and can be set using
654+
config.defaults['nyquist.start_marker'].
655+
656+
start_marker_size : float, optional
657+
Start marker size (in display coordinates). Default value is
658+
4 and can be set using config.defaults['nyquist.start_marker_size'].
659+
648660
warn_nyquist : bool, optional
649661
If set to 'False', turn off warnings about frequencies above Nyquist.
650662
@@ -713,6 +725,10 @@ def nyquist_plot(syslist, omega=None, plot=True, omega_limits=None,
713725
'nyquist', 'max_curve_magnitude', kwargs, _nyquist_defaults, pop=True)
714726
max_curve_offset = config._get_param(
715727
'nyquist', 'max_curve_offset', kwargs, _nyquist_defaults, pop=True)
728+
start_marker = config._get_param(
729+
'nyquist', 'start_marker', kwargs, _nyquist_defaults, pop=True)
730+
start_marker_size = config._get_param(
731+
'nyquist', 'start_marker_size', kwargs, _nyquist_defaults, pop=True)
716732

717733
# Set line styles for the curves
718734
def _parse_linestyle(style_name, allow_false=False):
@@ -848,6 +864,7 @@ def _parse_linestyle(style_name, allow_false=False):
848864
start_freq, p.imag + indent_radius, indent_points)),
849865
splane_contour[last_point:]))
850866

867+
# Indent points that are too close to a pole
851868
for i, s in enumerate(splane_contour):
852869
# Find the nearest pole
853870
p = splane_poles[(np.abs(splane_poles - s)).argmin()]
@@ -929,13 +946,21 @@ def _parse_linestyle(style_name, allow_false=False):
929946
'simple', head_width=arrow_size, head_length=arrow_size)
930947

931948
# Find the different portions of the curve (with scaled pts marked)
932-
reg_mask = abs(resp) > max_curve_magnitude
949+
reg_mask = np.logical_or(
950+
np.abs(resp) > max_curve_magnitude,
951+
contour.real != 0)
952+
# reg_mask = np.logical_or(
953+
# np.abs(resp.real) > max_curve_magnitude,
954+
# np.abs(resp.imag) > max_curve_magnitude)
955+
933956
scale_mask = ~reg_mask \
934957
& np.concatenate((~reg_mask[1:], ~reg_mask[-1:])) \
935958
& np.concatenate((~reg_mask[0:1], ~reg_mask[:-1]))
936959

937960
# Rescale the points with large magnitude
938-
resp[reg_mask] /= (np.abs(resp[reg_mask]) / max_curve_magnitude)
961+
rescale = np.logical_and(
962+
reg_mask, abs(resp) > max_curve_magnitude)
963+
resp[rescale] *= max_curve_magnitude / abs(resp[rescale])
939964

940965
# Plot the regular portions of the curve (and grab the color)
941966
x_reg = np.ma.masked_where(reg_mask, resp.real)
@@ -986,6 +1011,11 @@ def _parse_linestyle(style_name, allow_false=False):
9861011
_add_arrows_to_line2D(
9871012
ax, p[0], arrow_pos, arrowstyle=arrow_style, dir=-1)
9881013

1014+
# Mark the start of the curve
1015+
if start_marker:
1016+
plt.plot(resp[0].real, resp[0].imag, start_marker,
1017+
color=c, markersize=start_marker_size)
1018+
9891019
# Mark the -1 point
9901020
plt.plot([-1], [0], 'r+')
9911021

control/tests/nyquist_test.py

+7
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,13 @@ def test_linestyle_checks():
360360
test_nyquist_indent_do(indentsys)
361361
test_nyquist_indent_left(indentsys)
362362

363+
# Generate a figuring showing effects of different parameters
364+
sys = 3 * (s+6)**2 / (s * (s**2 + 1e-4 * s + 1))
365+
plt.figure()
366+
ct.nyquist_plot(sys)
367+
ct.nyquist_plot(sys, max_curve_magnitude=15)
368+
ct.nyquist_plot(sys, indent_radius=1e-6, max_curve_magnitude=25)
369+
363370
print("Unusual Nyquist plot")
364371
sys = ct.tf([1], [1, 3, 2]) * ct.tf([1], [1, 0, 1])
365372
plt.figure()

0 commit comments

Comments
 (0)