Skip to content

Incorrect indentation direction of poles in Nyquist plot #1191

Description

@INGELETTR

Hi there!
As title says, I found a problem with the following transfer function
num [1,11,10]
den = [0.01,1,0.01,1]

When specified indent_direction = "right", the control Nyquist plot is as follows.

Image The indentation curves are going counter-clockwise, while the general rule is to draw them clockwise! Is this a bug? if not, can I configure it to always encircle clockwise?

Also, changing indent_direction to "left" does not change the Nyquist diagram whatsoever.

Activity

  1. murrayrm commented on Jan 8, 2026

    @murrayrm
    Member

    What version of python-control are you running (use ct.__version__ to find out).

    One likely issue is that numerical approximations are giving poles that are not quite on the imaginary axis:

    >>> import control as ct
    >>> sys = ct.tf([1, 11, 10], [0.01,1,0.01,1])
    >>> sys.poles()
    array([-1.00000000e+02+0.j, -9.05723062e-16+1.j, -9.05723062e-16-1.j])
    

    As described in the documentation for nyquist_response:

    If a continuous-time system contains poles on or near the imaginary axis, a small indentation will be used to avoid the pole. The radius of the indentation is given by indent_radius and it is taken to the right of stable poles and the left of unstable poles. If a pole is exactly on the imaginary axis, the indent_direction parameter can be used to set the direction of indentation. Setting indent_direction to ‘none’ will turn off indentation.

    In this case, the pole is not "exactly on the imaginary axis" and so indent_direction is not used. Instead, since the real part of the pole is negative, the indentation will always be to the right (so that no new net encirclements are created).

    The curve that I get (with v0.10.2) is different than yours:

    Image
  2. INGELETTR commented on Jan 8, 2026

    @INGELETTR
    Author

    Hi there,
    I am using python control in a streamlit application, and in the requirements.txt i am requiring version >=0.10.2
    The transfer function is being created with the command
    self.sys = ct.TransferFunction(num, den)
    And the Nyquist plot called as follows
    ct.nyquist_plot(self.sys, omega=self.w, plot=True,indent_radius=0.2,indent_direction="right")

    To be completely transparent about it, I am quite new to this, and the code Is the only public repository in my profile, if you want to investigate it further.

  3. murrayrm commented on Jan 9, 2026

    @murrayrm
    Member

    What is setting self.w? I ran your command without that line (so that omega was chosen automatically) and got the same plot as I showed above.

    Getting omega right is important: you need to put in extra points in the indentation region since those points are very expanded. The nyquist_plot program does that automatically.

  4. murrayrm commented on Jan 19, 2026

    @murrayrm
    Member

    @INGELETTR Let us know if the above explanation fixes your issue.

    I'm going to open a separate issue about whether indent_direction should be used even when the poles are not exactly on the imaginary axis (it seems confusing in the case where you have small numerical errors, like this case).

  5. marko1olo commented on Aug 14, 2026

    @marko1olo

    Hi @felipericardo-fe!

    1. Why the indentation arc moves across these quadrants

    When indenting to the right around a pole at $s = j\omega_0$ in the $s$-plane with $s = j\omega_0 + \epsilon e^{j\theta}$ where $\theta \in [-\pi/2, +\pi/2]$:
    $$G(s) \approx \frac{R}{s - j\omega_0} = \frac{|R|}{\epsilon} e^{j(\phi_R - \theta)}$$
    where $R = |R| e^{j\phi_R}$ is the residue of $G(s)$ at that pole.

    For this transfer function, the pole is at $s = +1j$ with residue:
    $$R \approx 5.45 - 4.55j \implies \phi_R \approx -39.86^\circ$$

    As $\theta$ increases from $-90^\circ$ to $+90^\circ$ (tracing a clockwise detour in the $s$-plane):

    • At the start ($\theta = -90^\circ$): $\text{phase}(G(s)) = -39.86^\circ - (-90^\circ) = +50.14^\circ$ (Quadrant I)
    • At the end ($\theta = +90^\circ$): $\text{phase}(G(s)) = -39.86^\circ - (+90^\circ) = -129.86^\circ$ (Quadrant III)

    Because the phase decreases monotonically from $+50.14^\circ$ to $-129.86^\circ$, the large semicircular arc in the $G(s)$-plane is mathematically rotating clockwise (angle decreasing by $180^\circ$). The non-zero phase of the residue $\phi_R$ rotates the starting and ending angles, which is why it connects Quadrant I to Quadrant III instead of the right-half plane.

    2. Left vs. Right Indentation

    If you set indent_direction='left', $s = j\omega_0 - \epsilon e^{j\theta}$, the phase of $G(s)$ shifts by $180^\circ$, starting at $-129.86^\circ$ (Quadrant III) and ending at $+50.14^\circ$ (Quadrant I) in counter-clockwise phase progression.

  6. slivingston commented on Aug 15, 2026

    @slivingston
    Member

    Hi @felipericardo-fe!

    This does not seem to be a user on this issue. @marko1olo, just to confirm, was your post written by an agent like Codex or Claude etc.?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions