---
title: "RootLocusPlot"
language: "en"
type: "Symbol"
summary: "RootLocusPlot[lsys, {k, kmin, kmax}] generates a root locus plot of a linear time-invariant system lsys as the parameter k ranges from kmin to kmax."
keywords: 
- root locus plot
- root loci
- closed loop eigenvalues
- closed loop poles
- closed loop roots
- damping ratio
- natural frequency
- bandwidth
- positive feedback
- negative feedback
- closed loop system
- control systems
- control theory
- rlocus
canonical_url: "https://reference.wolfram.com/language/ref/RootLocusPlot.html"
source: "Wolfram Language Documentation"
related_guides: 
  - 
    title: "Classical Analysis and Design"
    link: "https://reference.wolfram.com/language/guide/ClassicalAnalysisAndDesign.en.md"
  - 
    title: "Control Systems"
    link: "https://reference.wolfram.com/language/guide/ControlSystems.en.md"
related_functions: 
  - 
    title: "TransferFunctionModel"
    link: "https://reference.wolfram.com/language/ref/TransferFunctionModel.en.md"
  - 
    title: "NRoots"
    link: "https://reference.wolfram.com/language/ref/NRoots.en.md"
---
# RootLocusPlot

RootLocusPlot[lsys, {k, kmin, kmax}] generates a root locus plot of a linear time-invariant system lsys as the parameter k ranges from kmin to kmax.

## Details and Options

* ``RootLocusPlot`` plots the location of poles for the closed-loop system for a range of ``k`` values.

* ``RootLocusPlot`` treats the parameter ``k`` as local, effectively using ``Block``.

* The systems model ``lsys`` can be a ``StateSpaceModel`` or a ``TransferFunctionModel``.

* ``RootLocusPlot`` has the same options as ``Graphics``, with the following additions and changes: []

|                       |                   |                                                       |
| --------------------- | ----------------- | ----------------------------------------------------- |
| Axes                  | True              | whether to draw axes                                  |
| ColorFunction         | Automatic         | how to apply coloring to the loci                     |
| ColorFunctionScaling  | True              | whether to scale arguments to ColorFunction           |
| EvaluationMonitor     | None              | expression to evaluate at every parameter evaluation  |
| Exclusions            | Automatic         | parameter values to exclude                           |
| ExclusionsStyle       | None              | what to draw at excluded points                       |
| FeedbackType          | "Negative"        | feedback type                                         |
| MaxRecursion          | Automatic         | the maximum number of recursive subdivisions allowed  |
| Mesh                  | Automatic         | how many mesh divisions to draw                       |
| MeshFunctions         | Automatic         | how to determine the placement of the mesh divisions  |
| MeshShading           | None              | how to shade regions between mesh points              |
| MeshStyle             | None              | the style for mesh divisions                          |
| Method                | Automatic         | the method to determine the loci                      |
| PerformanceGoal       | \$PerformanceGoal | aspects of performance to try to optimize             |
| PlotPoints            | Automatic         | initial number of sample parameter points             |
| PlotRange             | Automatic         | range of values to include                            |
| PlotRangeClipping     | True              | whether to clip at the plot range                     |
| PlotStyle             | Automatic         | graphics directives to specify the style for the loci |
| PlotTheme             | \$PlotTheme       | overall theme for the plot                            |
| PoleZeroMarkers       | Automatic         | markers for poles and zeros                           |
| RegionFunction        | (True&)           | how to determine whether a point should be included   |
| PlotLegends           | None              | legends for root loci                                 |
| WorkingPrecision      | MachinePrecision  | the precision used in internal computations           |

* ``RootLocusPlot`` takes a ``Method`` option that specifies the method used for computing the root loci.

* With the setting ``Method -> "GenericSolve"``, the loci are determined by computing the roots at the sample points and then sorting them.

* With ``Method -> "NDSolve"``, ``RootLocusPlot`` uses ``NDSolve`` to solve the differential equation $\frac{\partial f}{\partial s}\frac{ds}{dk}+\frac{\partial f}{\partial k}=0$, where $f(s,k)=0$ is the characteristic equation of the closed-loop system and $s$ is the complex variable.

* ``Method -> {"NDSolve", opt1 -> val1, opt2 -> val2, …}`` uses the specified ``NDSolve`` options.

* The closed-loop poles for specific values of ``k`` can be plotted with appropriate settings for ``Mesh``, ``MeshFunctions``, and ``MeshStyle``.

* ``ColorData["DefaultPlotColors"]`` gives the default sequence of colors used by ``PlotStyle``.

* Markers for open-loop poles and zeros, as well as closed-loop poles, can be specified by setting the ``PoleZeroMarkers`` option.

* The arguments to ``RegionFunction`` are ``x``, ``y``, and ``k``.

### List of all options

|                        |                   |                                                                                    |
| ---------------------- | ----------------- | ---------------------------------------------------------------------------------- |
| AlignmentPoint         | Center            | the default point in the graphic to align with                                     |
| AspectRatio            | Automatic         | ratio of height to width                                                           |
| Axes                   | True              | whether to draw axes                                                               |
| AxesLabel              | None              | axes labels                                                                        |
| AxesOrigin             | Automatic         | where axes should cross                                                            |
| AxesStyle              | {}                | style specifications for the axes                                                  |
| Background             | None              | background color for the plot                                                      |
| BaselinePosition       | Automatic         | how to align with a surrounding text baseline                                      |
| BaseStyle              | {}                | base style specifications for the graphic                                          |
| ColorFunction          | Automatic         | how to apply coloring to the loci                                                  |
| ColorFunctionScaling   | True              | whether to scale arguments to ColorFunction                                        |
| ContentSelectable      | Automatic         | whether to allow contents to be selected                                           |
| CoordinatesToolOptions | Automatic         | detailed behavior of the coordinates tool                                          |
| Epilog                 | {}                | primitives rendered after the main plot                                            |
| EvaluationMonitor      | None              | expression to evaluate at every parameter evaluation                               |
| Exclusions             | Automatic         | parameter values to exclude                                                        |
| ExclusionsStyle        | None              | what to draw at excluded points                                                    |
| FeedbackType           | "Negative"        | feedback type                                                                      |
| FormatType             | TraditionalForm   | the default format type for text                                                   |
| Frame                  | False             | whether to put a frame around the plot                                             |
| FrameLabel             | None              | frame labels                                                                       |
| FrameStyle             | {}                | style specifications for the frame                                                 |
| FrameTicks             | Automatic         | frame ticks                                                                        |
| FrameTicksStyle        | {}                | style specifications for frame ticks                                               |
| GridLines              | None              | grid lines to draw                                                                 |
| GridLinesStyle         | {}                | style specifications for grid lines                                                |
| ImageMargins           | 0.                | the margins to leave around the graphic                                            |
| ImagePadding           | All               | what extra padding to allow for labels etc.                                        |
| ImageSize              | Automatic         | the absolute size at which to render the graphic                                   |
| LabelStyle             | {}                | style specifications for labels                                                    |
| MaxRecursion           | Automatic         | the maximum number of recursive subdivisions allowed                               |
| Mesh                   | Automatic         | how many mesh divisions to draw                                                    |
| MeshFunctions          | Automatic         | how to determine the placement of the mesh divisions                               |
| MeshShading            | None              | how to shade regions between mesh points                                           |
| MeshStyle              | None              | the style for mesh divisions                                                       |
| Method                 | Automatic         | the method to determine the loci                                                   |
| PerformanceGoal        | \$PerformanceGoal | aspects of performance to try to optimize                                          |
| PlotLabel              | None              | an overall label for the plot                                                      |
| PlotLegends            | None              | legends for root loci                                                              |
| PlotPoints             | Automatic         | initial number of sample parameter points                                          |
| PlotRange              | Automatic         | range of values to include                                                         |
| PlotRangeClipping      | True              | whether to clip at the plot range                                                  |
| PlotRangePadding       | Automatic         | how much to pad the range of values                                                |
| PlotRegion             | Automatic         | the final display region to be filled                                              |
| PlotStyle              | Automatic         | graphics directives to specify the style for the loci                              |
| PlotTheme              | \$PlotTheme       | overall theme for the plot                                                         |
| PoleZeroMarkers        | Automatic         | markers for poles and zeros                                                        |
| PreserveImageOptions   | Automatic         | whether to preserve image options when displaying new versions of the same graphic |
| Prolog                 | {}                | primitives rendered before the main plot                                           |
| RegionFunction         | (True&)           | how to determine whether a point should be included                                |
| RotateLabel            | True              | whether to rotate y labels on the frame                                            |
| Ticks                  | Automatic         | axes ticks                                                                         |
| TicksStyle             | {}                | style specifications for axes ticks                                                |
| WorkingPrecision       | MachinePrecision  | the precision used in internal computations                                        |

---

## Examples (59)

### Basic Examples (2)

Root locus plot of a transfer-function model:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*(1 + s)}}, 
  (-1 + s)*s*(16 + 4*s + s^2)}, s], {k, 0, 80}]

Out[1]= [image]
```

---

Root loci of a state-space model:

```wl
In[1]:=
RootLocusPlot[StateSpaceModel[{{{0, 1}, {-3, -2}}, {{0}, {1}}, {{2*k, k}}, {{0}}}, 
 SamplingPeriod -> None, SystemsModelLabels -> None], {k, 0, 8}]

Out[1]= [image]
```

### Scope (3)

The root locus plot for various pole-zero configurations:

```wl
In[1]:=
Grid[Partition[Table[RootLocusPlot[sys, {k, 0, 10}, PlotLabel -> sys, ImageSize -> 180], {sys, {TransferFunctionModel[{{{k}}, s*(1 + s)*
   (2 + s)}, s], TransferFunctionModel[{{{k}}, (1 + s)*
   (1 + s + s^2)}, s], TransferFunctionModel[{{{k}}, 0.5*s + 1.5*s^2 + 
   2.*s^3 + s^4}, s, SamplingPeriod -> None, 
 SystemsModelLabels -> None], TransferFunctionModel[{{{k}}, s*(1 + s)*
   (1 + s + s^2)}, s], TransferFunctionModel[{{{k}}, 0.5 + 1.5*s + 2.5*s^2 + 
   2.*s^3 + s^4}, s, SamplingPeriod -> None, 
 SystemsModelLabels -> None], TransferFunctionModel[{{{k}}, (2 + 2*s + s^2)*
   (5 + 4*s + s^2)}, s], TransferFunctionModel[{{{k}}, s*(1 + s)*
   (2 + 2*s + s^2)}, s], TransferFunctionModel[{{{k}}, 5.*s + 7.*s^2 + 
   4.5*s^3 + s^4}, s, SamplingPeriod -> None, 
 SystemsModelLabels -> None], TransferFunctionModel[{{{k}}, s*(1 + s)*(2 + s)*
   (1 + s + s^2)}, s], TransferFunctionModel[{{{k*s}}, 
  12 + 2*s + s^2}, s], TransferFunctionModel[{{{10.*k + k*s}}, 
  2.5 + 6.*s + 2.5*s^2 + s^3}, s, 
 SamplingPeriod -> None, SystemsModelLabels -> None], TransferFunctionModel[{{{0.65*k + k*s}}, 
  1.25*s + 5.5*s^2 + 2.25*s^3 + s^4}, 
 s, SamplingPeriod -> None, SystemsModelLabels -> None], TransferFunctionModel[{{{k*(1 + s)}}, 
  (1 + s + s^2)*(6 + 4*s + s^2)}, 
 s], TransferFunctionModel[{{{k*(18 + 4*s + s^2)}}, 
  s*(2 + s)*(5 + s)}, s]}}], 2], Frame -> All, Spacings -> 3]

Out[1]=
|         |         |
| ------- | ------- |
| [image] | [image] |
| [image] | [image] |
| [image] | [image] |
| [image] | [image] |
| [image] | [image] |
| [image] | [image] |
| [image] | [image] |
```

---

Root locus plot of a ``TransferFunctionModel`` :

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*(3 + s)}}, 
  3 + s + 2*s^2 + s^3 + s^4}, s], {k, 0, 200}]

Out[1]= [image]
```

---

Root locus plot of a ``StateSpaceModel`` :

```wl
In[1]:=
RootLocusPlot[StateSpaceModel[{{{0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}, {-3, -1, -2, -1}}, 
  {{0}, {0}, {0}, {1}}, {{3*k, 4*k, 4*k, k}}, 
  {{0}}}, SamplingPeriod -> None, SystemsModelLabels -> None], {k, 0, 10}]

Out[1]= [image]
```

### Generalizations & Extensions (1)

A root locus plot can be obtained from a transfer-function model or directly from its expression:

```wl
In[1]:= g = k (s^2 + 2 s + 4/s(s + 4)(s + 6)(s^2 + 1.4s + 1));

In[2]:= {RootLocusPlot[TransferFunctionModel[g, s], {k, 0, 150}], RootLocusPlot[g, {k, 0, 150}]}

Out[2]= {[image], [image]}
```

### Options (43)

#### AspectRatio (4)

By default, the ratio of the height to width for the plot is determined automatically:

```wl
In[1]:= RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}]

Out[1]= [image]
```

---

Make the height the same as the width with ``AspectRatio -> 1`` :

```wl
In[1]:= RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, AspectRatio -> 1]

Out[1]= [image]
```

---

Use numerical values to specify the height-to-width ratio:

```wl
In[1]:= RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, AspectRatio -> 1 / 2]

Out[1]= [image]
```

---

``AspectRatio -> Full`` adjusts the height and width to tightly fit inside other constructs:

```wl
In[1]:= plot = RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, AspectRatio -> Full];

In[2]:= {Framed[Pane[plot, {50, 100}]], Framed[Pane[plot, {100, 100}]], Framed[Pane[plot, {100, 50}]]}

Out[2]= {[image], [image], [image]}
```

#### Axes (3)

By default, ``Axes`` are drawn:

```wl
In[1]:= RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}]

Out[1]= [image]
```

---

Use ``Axes -> False`` to turn off axes:

```wl
In[1]:= RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, Axes -> False]

Out[1]= [image]
```

---

Turn each axis on individually:

```wl
In[1]:= {RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, Axes -> {True, False}], RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, Axes -> {False, True}]}

Out[1]= {[image], [image]}
```

#### AxesLabel (3)

No axes labels are drawn by default:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*(1 + s)}}, 
  (-1 + s)*s*(16 + 4*s + s^2)}, s], {k, 0, 80}]

Out[1]= [image]
```

---

Place a label on the $y$ axis:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*(1 + s)}}, 
  (-1 + s)*s*(16 + 4*s + s^2)}, s], {k, 0, 80}, AxesLabel -> Im]

Out[1]= [image]
```

---

Specify axes labels:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*(1 + s)}}, 
  (-1 + s)*s*(16 + 4*s + s^2)}, s], {k, 0, 80}, AxesLabel -> {Re, Im}]

Out[1]= [image]
```

#### AxesOrigin (2)

The position of the axes is determined automatically:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*(1 + s)}}, 
  (-1 + s)*s*(16 + 4*s + s^2)}, s], {k, 0, 80}]

Out[1]= [image]
```

---

Specify an explicit origin for the axes:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*(1 + s)}}, 
  (-1 + s)*s*(16 + 4*s + s^2)}, s], {k, 0, 80}, AxesOrigin -> {-3, 0}]

Out[1]= [image]
```

#### AxesStyle (3)

Change the style for the axes:

```wl
In[1]:= RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, AxesStyle -> Red]

Out[1]= [image]
```

---

Specify the style of each axis:

```wl
In[1]:= RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, AxesStyle -> {{Thick, Red}, {Thick, Blue}}]

Out[1]= [image]
```

---

Use different styles for the ticks and the axes:

```wl
In[1]:= RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, AxesStyle -> Green, TicksStyle -> Black]

Out[1]= [image]
```

#### ColorFunction (1)

Color stable and unstable parts green and red for a continuous-time system:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k}}, 2 + 5*s + 4*s^2 + 
   s^3}, s], {k, 0, 55}, ColorFunction -> Function[{x, y, k}, If[x < 0, Green, Red]], ColorFunctionScaling -> False]

Out[1]= [image]
```

For a discrete-time system:

```wl
In[2]:=
RootLocusPlot[TransferFunctionModel[{{{k + k*z}}, 
  0.25 + 0.866025*z + z^2}, z, SamplingPeriod -> 1, 
 SystemsModelLabels -> None], {k, 0, 3}, ColorFunction -> Function[{x, y, k}, If[Sqrt[x^2 + y^2] < 1, Green, Red]], ColorFunctionScaling -> False]

Out[2]= [image]
```

#### Epilog (3)

Show lines corresponding to a damping ratio 0.4 on the $s$ plane:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k}}, 1.5*s + 2.5*s^2 + 
   s^3}, s], {k, 0, 1.5}, Epilog -> Line[{{-ζ ω, -ω Sqrt[1 - ζ^2]}, {0, 0}, {-ζ ω, ω Sqrt[1 - ζ^2]}} /.  {ω -> 1, ζ -> 0.4}]]

Out[1]= [image]
```

---

Show the circle corresponding to the natural frequency 3 radians per time unit:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*(2 + s)}}, 
  1 + 4*s + s^3}, s], {k, 0, 10}, Epilog -> Circle[{0, 0}, 3], PlotRange -> 3.5]

Out[1]= [image]
```

---

The loci of points with damping 0.4 in the $z$ plane for a system with sampling period 1:

```wl
In[1]:=
Show[RootLocusPlot[TransferFunctionModel[{{{0.25*k + k*z}}, 
  -0.6 - 1.7*z - 1.*z^2 + z^3}, z, 
 SamplingPeriod -> 1], {k, 0, 3.5}], ParametricPlot[Exp[-ζ Subscript[ω, n] T] {{Cos[Subscript[ω, n] Sqrt[1 - ζ^2] T], Sin[Subscript[ω, n] Sqrt[1 - ζ^2] T]}, {Cos[Subscript[ω, n] Sqrt[1 - ζ^2] T], -Sin[Subscript[ω, n] Sqrt[1 - ζ^2] T]}} /.  {ζ -> 0.4, T -> 1}, {Subscript[ω, n], 0, π}, PlotStyle -> Directive[Dashed, Black]]]

Out[1]= [image]
```

#### FeedbackType (3)

Negative feedback is assumed by default:

```wl
In[1]:=
tfm = TransferFunctionModel[{{{k}}, 1 - s + 2*s^2 + 
   s^3}, s];

In[2]:= RootLocusPlot[tfm, {k, 0, 24}]

Out[2]= [image]
```

Positive feedback:

```wl
In[3]:= RootLocusPlot[tfm, {k, 0, 24}, FeedbackType -> "Positive"]

Out[3]= [image]
```

---

Root loci of an open-loop system with positive feedback:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*(34 + 10*s + s^2)}}, 
  12 + 26*s + 22*s^2 + 9*s^3 + s^4}, 
 s], {k, 0, 30}, FeedbackType -> "Positive"]

Out[1]= [image]
```

---

A closed-loop system:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*s}}, 
  1 + s + k*s^2 + s^3}, s], {k, 0, 2}, FeedbackType -> None]

Out[1]= [image]
```

#### ImageSize (7)

Use named sizes, such as ``Tiny``, ``Small``, ``Medium`` and ``Large`` :

```wl
In[1]:= {RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, ImageSize -> Tiny], RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, ImageSize -> Small]}

Out[1]= {[image], [image]}
```

---

Specify the width of the plot:

```wl
In[1]:= {RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, ImageSize -> 100], RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, AspectRatio -> 1.5, ImageSize -> 100]}

Out[1]= {[image], [image]}
```

Specify the height of the plot:

```wl
In[2]:= {RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, ImageSize -> {Automatic, 150}], RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, AspectRatio -> 2, ImageSize -> {Automatic, 150}]}

Out[2]= {[image], [image]}
```

---

Allow the width and height to be up to a certain size:

```wl
In[1]:= {RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, ImageSize -> UpTo[200]], RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, AspectRatio -> 1, ImageSize -> UpTo[200]]}

Out[1]= {[image], [image]}
```

---

Specify the width and height for a graphic, padding with space if necessary:

```wl
In[1]:= RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, ImageSize -> {200, 200}, Background -> LightBlue]

Out[1]= [image]
```

Setting ``AspectRatio -> Full`` will fill the available space:

```wl
In[2]:= RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, AspectRatio -> Full, ImageSize -> {200, 200}, Background -> LightBlue]

Out[2]= [image]
```

---

Use maximum sizes for the width and height:

```wl
In[1]:= {RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, ImageSize -> {UpTo[150], UpTo[100]}], RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, AspectRatio -> 2, ImageSize -> {UpTo[150], UpTo[100]}]}

Out[1]= {[image], [image]}
```

---

Use ``ImageSize -> Full`` to fill the available space in an object:

```wl
In[1]:= Framed[Pane[RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, ImageSize -> Full, Background -> LightBlue], {200, 200}]]

Out[1]= [image]
```

---

Specify the image size as a fraction of the available space:

```wl
In[1]:= Framed[Pane[RootLocusPlot[TransferFunctionModel[{{{k (-3 + s)}}, 1 + s^3}, s], {k, 0, 5}, AspectRatio -> Full, ImageSize -> {Scaled[0.5], Scaled[0.5]}, Background -> LightBlue], {200, 100}]]

Out[1]= [image]
```

#### Method (1)

The ``"NDSolve"`` method can be faster than ``"GenericSolve"`` :

```wl
In[1]:=
tfm = TransferFunctionModel[{{{9.*k + 544.575*k*s + 
     7474.6*k*s^2 + 3666.03125*k*s^3 + 
     81.875*k*s^4 + 25.*k*s^5}}, 
  640.*s + 6855.999999999999*s^2 + 4685.6*s^3 + 
   1274.5*s^4 + 186.8*s^5 + 18.1*s^6 + s^7}, 
 s];

In[2]:= Table[Timing[RootLocusPlot[tfm, {k, 0, 20}, Method -> m]], {m, {"NDSolve", "GenericSolve"}}]

Out[2]= {{0.640625, [image]}, {0.265625, [image]}}
```

#### PlotLegends (4)

Use placeholder legends for root loci:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*(10 + s)}}, 
  20 + 6*s + s^2}, s], {k, 0, 30}, PlotLegends -> Automatic]

Out[1]= [image]
```

---

Use a list of legend text:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*(10 + s)}}, 
  20 + 6*s + s^2}, s], {k, 0, 30}, PlotLegends -> {"one", "two"}]

Out[1]= [image]
```

---

Use ``LineLegend`` to add a overall legend label:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*(10 + s)}}, 
  20 + 6*s + s^2}, s], {k, 0, 30}, PlotLegends -> LineLegend[{"one", "two"}, LegendLabel -> "ζ"]]

Out[1]= [image]
```

---

Place the legend above the plot:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*(10 + s)}}, 
  20 + 6*s + s^2}, s], {k, 0, 30}, PlotLegends -> Placed[{"one", "two"}, Above]]

Out[1]= [image]
```

#### PlotTheme (2)

Use a theme with a frame and grid lines:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*(1 + s + s^2)}}, 
  1 + 3*s - 4*s^2 + s^3}, s], {k, 0, 16}, PlotTheme -> "Detailed"]

Out[1]= [image]
```

---

Change the style of the grid lines:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*(1 + s + s^2)}}, 
  1 + 3*s - 4*s^2 + s^3}, s], {k, 0, 16}, PlotTheme -> "Detailed", GridLinesStyle -> LightGray]

Out[1]= [image]
```

#### PoleZeroMarkers (6)

By default, open-loop poles at zero and closed-loop poles at the mean parameter value are shown:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*s}}, 
  10 + s + 5*s^2 + s^3}, s], {k, 0, 20}]

Out[1]= [image]
```

---

Show no markers:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[
 {{{k*(3 + s)*(1 + s + s^2)}}, 
  3 + s + 2*s^2 + s^3 + s^4}, s], {k, 0, 10}, PoleZeroMarkers -> None]

Out[1]= [image]
```

---

Show the closed-loop poles only:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[
 {{{k*(1 + s)*(1 + s + s^2)}}, 
  3 + s + 2*s^2 + s^3 + s^4}, s], {k, 0, 10}, PoleZeroMarkers -> {"", Automatic, ""}]

Out[1]= [image]
```

---

Use text or typeset labels:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*(10 + s)}}, 
  20 + 6*s + s^2}, s], {k, 0, 30}, PoleZeroMarkers -> (Style[#, Larger, Background -> LightGreen]& /@ {"p", "cl", "z"})]

Out[1]= [image]
```

---

Use graphics primitives as the pole-zero markers:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*(-3 + s)*(-1 + s)}}, 
  (2 + s)*(4 + s)}, s], {k, 0, 4}, PoleZeroMarkers -> {Graphics[{Black, Text["X"]}], Graphics[{Red, Text["X"]}], Graphics[{Green, Disk[{0, 0}, Scaled[0.03]]}]}, PlotRange -> All]

Out[1]= [image]
```

---

Use any 2D or 3D graphics:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k*(1 + s + s^2)}}, 
  1 + 3*s - 4*s^2 + s^3}, s], {k, 0, 16}, PoleZeroMarkers -> {[image], [image], [image]}]

Out[1]= [image]
```

#### RegionFunction (1)

Show the loci only in the region where the closed-loop system is stable:

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k + k*z}}, 
  0.2 - 1.2*z + z^2}, z, SamplingPeriod -> 1, 
 SystemsModelLabels -> None], {k, 0, 5}, RegionFunction -> Function[{x, y, k}, Sqrt[x^2 + y^2] < 1]]

Out[1]= [image]
```

### Applications (3)

Explore and determine critical points such as break-away, break-in, and imaginary axis crossings:

```wl
In[1]:=
Manipulate[RootLocusPlot[TransferFunctionModel[{{{100*k*s*(10 + s)}}, 
  (-10 + s)*(25 + s)*(-225 + s^2)}, s], {k, 0, 30}, PlotRange -> All, AspectRatio -> 1, PoleZeroMarkers -> {Automatic, "ParameterValues" -> kVal}], {kVal, 0, 30}]

Out[1]= DynamicModule[«7»]
```

---

Plot the roots of a polynomial as a parameter is varied:

```wl
In[1]:=
poly = s^3 + k s^2 + s + 1;
RootLocusPlot[k Ratios[CoefficientList[poly, k]], {k, 0, 3}]

Out[1]= [image]
```

---

Analyze the effect of the sensor gain on a system:

[image]

```wl
In[1]:=
closedLoop = SystemsModelFeedbackConnect[TransferFunctionModel[{{{0.5*(0.5 + s)*(1 + 0.5*s + s^2)}}, 
  (-0.5 + s)*(0.75 + s)*(2.5 + s)*
   (1.5 + 2*s + s^2)}, s], TransferFunctionModel[{{{k}}, 1}, \[FormalS]]];

In[2]:= RootLocusPlot[closedLoop, {k, 0, 12}, FeedbackType -> None]

Out[2]= [image]
```

### Properties & Relations (6)

The root-locus consists of points with $\text{\textit{$\arg $}}(\text{\textit{tfm}})=\pi$ for negative feedback:

```wl
In[1]:= tfm = (1/s(s + 1)^2) /. s -> x + I y;

In[2]:= sp = StreamPlot[ReIm[tfm], {x, -2.5, 2.5}, {y, -2.5, 2.5}, StreamPoints -> 25, StreamScale -> Large, StreamStyle -> Lighter[Brown], StreamColorFunction -> None];

In[3]:= Show[sp, RootLocusPlot[k(1/s(s + 1)^2), {k, 0, 12}, FeedbackType -> "Negative"]]

Out[3]= [image]
```

And points with $\text{\textit{$\arg $}}(\text{\textit{tfm}})=0$ for positive feedback:

```wl
In[4]:= Show[sp, RootLocusPlot[k(1/s(s + 1)^2), {k, 0, 12}, FeedbackType -> "Positive"]]

Out[4]= [image]
```

---

The root locus plot does not depend on the sampling period:

```wl
In[1]:=
Table[RootLocusPlot[TransferFunctionModel[{{{2.*k + k*s}}, 
  2.5*s + 6.*s^2 + 2.5*s^3 + s^4}, 
 s, SamplingPeriod -> τ], {k, 0, 70}], {τ, {None, 1}}]

Out[1]= {[image], [image]}
```

---

For strictly proper systems, the root loci go to infinity with straight-line asymptotes:

```wl
In[1]:=
tfm = TransferFunctionModel[{{{k*(1 + s)}}, 
  1820 + 2234*s + 1024*s^2 + 225*s^3 + 24*s^4 + 
   s^5}, s]//N;
```

For the strictly proper system, the number of poles is greater than the number of zeros:

```wl
In[2]:= {p, z} = Flatten /@ {TransferFunctionPoles[tfm], TransferFunctionZeros[tfm]}

Out[2]= {{-7., -5. - 1. I, -5. + 1. I, -5., -2.}, {-1.}}
```

The plot shows four loci going to infinity:

```wl
In[3]:= RootLocusPlot[tfm, {k, 0, 100}]

Out[3]= [image]
```

The slopes of the asymptotes for a negative feedback system:

```wl
In[4]:= m = Table[Tan[((2 j - 1) π/(Length[p] - Length[z]))], {j, 1, Length[p] - Length[z]}]

Out[4]= {1, -1, 1, -1}
```

Find where the asymptotes intercept the real axis:

```wl
In[5]:= Subscript[σ, a] = (Total[p] - Total[z]/Length[p] - Length[z])//Chop

Out[5]= -5.75
```

Plot the root loci and the asymptotes:

```wl
In[6]:= asymptotes = m /. {ComplexInfinity -> x == Subscript[σ, a], m_ ? NumericQ :> y == m (x - Subscript[σ, a])};

In[7]:= Show[RootLocusPlot[tfm, {k, 0, 100}], ContourPlot[Evaluate[asymptotes], {x, -8, 0}, {y, -2.5, 2.5}, ContourStyle -> Dashed]]

Out[7]= [image]
```

The slopes of the asymptotes for a positive feedback system:

```wl
In[8]:= m = Table[Tan[(2 j π/(Length[p] - Length[z]))], {j, 1, Length[p] - Length[z]}]

Out[8]= {ComplexInfinity, 0, ComplexInfinity, 0}
```

Plot the root loci and the asymptotes:

```wl
In[9]:= asymptotes = m /. {ComplexInfinity -> x == Subscript[σ, a], m_ ? NumericQ :> y == m( x - Subscript[σ, a])};

In[10]:= Show[RootLocusPlot[tfm, {k, 0, 100}, FeedbackType -> "Positive", PlotRange -> All], ContourPlot[Evaluate[asymptotes], {x, -10, 0}, {y, -3.2, 3.2}, ContourStyle -> Dashed]]

Out[10]= [image]
```

---

The break-away and break-in points on the real axis can be computed from the poles and zeros:

```wl
In[1]:=
tfm = TransferFunctionModel[{{{k*s*(2 + s)}}, 
  (4 + s)*(5 + s)*(6 + s)*(8 + s)}, 
 s];

In[2]:= {p, z} = Flatten /@ {TransferFunctionPoles[tfm], TransferFunctionZeros[tfm]};

In[3]:= sols = NSolve[Underoverscript[∑, i = 1, Length[p]](1/x - p[[i]]) == Underoverscript[∑, i = 1, Length[z]](1/x - z[[i]]) , x]

Out[3]= {{x -> -7.20763}, {x -> -5.4764}, {x -> -4.33055}, {x -> 3.94}, {x -> -1.42542}}
```

Select those points for which ``k∈Interval[{0, 5}]`` :

```wl
In[4]:= charEqs = Flatten[Denominator[SystemsModelFeedbackConnect[tfm][x]] /. sols];

In[5]:= Subscript[k, crit] = k /. Map[NSolve[# == 0, k][[1]]&, charEqs];

In[6]:= Subscript[σ, b] = x /. Pick[sols, Map[0 ≤ # ≤ 5&, Subscript[k, crit]]]

Out[6]= {-7.20763, -4.33055}
```

Show the points on the root locus plot:

```wl
In[7]:= RootLocusPlot[tfm, {k, 0, 5}, Epilog -> {PointSize[Large], Point[{#, 0}& /@ Subscript[σ, b]]}, PoleZeroMarkers -> None]

Out[7]= [image]
```

---

With the loci and closed-loop poles removed, it becomes a pole-zero plot of the open-loop system:

```wl
In[1]:= RootLocusPlot[k (z^2 + 0.25 /z^2 - 0.25), {k, 0, 1}, PlotRange -> {-1, 1}, AspectRatio -> 1, PlotStyle -> None, PoleZeroMarkers -> {Automatic, "", Automatic}]

Out[1]= [image]
```

Compute the poles and zeros:

```wl
In[2]:=
tfm = TransferFunctionModel[ (z^2 + 0.25 /z^2 - 0.25), z, SamplingPeriod -> 1];
pz = Flatten /@ {TransferFunctionPoles[tfm], TransferFunctionZeros[tfm]}

Out[2]= {{-0.5, 0.5}, {0.  - 0.5 I, 0.  + 0.5 I}}
```

Use ``ListPlot`` to show the same pole-zero plot:

```wl
In[3]:= ListPlot[Map[ReIm, pz, {2}], PlotRange -> {-1, 1}, AspectRatio -> 1, PlotMarkers -> {[image], [image]}]

Out[3]= [image]
```

---

The complex-valued transfer function is a surface with "peaks" at the poles and "valleys" at the zeros:

```wl
In[1]:= sys = (s^2 + 10s + 125/s(s + 20));

In[2]:= tf[{x_, y_}] := 20Log10@Abs[sys /. s -> x + I y]

In[3]:= p1 = Plot3D[tf[{x, y}], {x, -30, 5}, {y, -20, 20}, PlotStyle -> Yellow, AxesLabel -> {"x", "y", "z"}, MeshFunctions -> {#3&}, Mesh -> {Range[-25, 25, 2]}, ClippingStyle -> None, ImageSize -> Medium]

Out[3]= [image]
```

The root locus plot travels from the "peaks" to the "valleys" along the lines of steepest descent:

```wl
In[4]:= rlPlot = RootLocusPlot[k sys, {k, 0, 90}, PlotRange -> All, PlotPoints -> 270, PoleZeroMarkers -> None];

In[5]:= pts = Cases[FullForm@rlPlot, l_Line :> l, Infinity];

In[6]:= projection = ReleaseHold@Quiet@Replace[pts, xy_ :> Check[Join[xy, {tf[xy]}], Hold@Sequence[]], {3}];

In[7]:= p2 = Show[p1, Graphics3D[Riffle[{Directive[Thick, Red], Directive[Thick, Blue]}, projection]]]

Out[7]= [image]
```

The Bode magnitude plot is the intersection of the surface and the $y$ - $z$ plane:

```wl
In[8]:= bMagPlot = BodePlot[sys, {-20, 20}, ScalingFunctions -> {"Linear", Automatic}, PlotLayout -> "Magnitude"];

In[9]:= magPts = Cases[FullForm@bMagPlot, l_Line :> l, Infinity];

In[10]:= magPts3D = Replace[magPts, xy_ :> Join[{0}, xy], {3}];

In[11]:= Show[p2, Graphics3D[{Directive[Thickness[0.01], Orange], magPts3D}]]

Out[11]= [image]
```

### Possible Issues (1)

The root loci may not be symmetric with respect to the real axis (but the roots are):

```wl
In[1]:=
RootLocusPlot[TransferFunctionModel[{{{k}}, 0.5*s + 1.5*s^2 + 
   2.*s^3 + s^4}, s], {k, 0, 10}]

Out[1]= [image]
```

## See Also

* [`TransferFunctionModel`](https://reference.wolfram.com/language/ref/TransferFunctionModel.en.md)
* [`NRoots`](https://reference.wolfram.com/language/ref/NRoots.en.md)

## Related Guides

* [Classical Analysis and Design](https://reference.wolfram.com/language/guide/ClassicalAnalysisAndDesign.en.md)
* [Control Systems](https://reference.wolfram.com/language/guide/ControlSystems.en.md)

## History

* [Introduced in 2010 (8.0)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn80.en.md) \| [Updated in 2012 (9.0)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn90.en.md) ▪ [2014 (10.0)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn100.en.md)