# Root locus plots using LaTeX

On my homework, I need to create a root locus plot.

Wondering if anyone out there has good suggestions for a package that is able to create root locus plots, or a general plotting package that is powerful and easy enough to use for this purpose.

I found this neat post with a link to a script to create TikZ drawing code from MATLAB plotting tools, however I'm using this from my home server with no X11 access so it's most likely not going to work well (although I haven't tried yet). I would prefer something that's pure LaTeX though for ease of use.

• I'm always amazed that universities still teach root loci. You can artificially create a table of points where each root is moving with parameter dependence. And then once you have a table then it is fairly simple to do with pgfplots. – percusse Nov 21 '14 at 1:52
• Right? This is a grad level course too, and the professor has spent like 3 lectures on it. I would love to learn more modern stuff, but this stuff is good to know for the intuition for the modern control stuff. The professor told us a story where he said Root Locus method was invented by some UCLA grad student's thesis paper. – fubuloubu Nov 21 '14 at 1:59

I still don't know why they teach root locus still in 2014 but they are skipping the actual engineering part that is using the spirule which made the Root Locus method useful in the first place. Otherwise it was as computationally demanding as other methods. But nevermind.

Consider the following snippet

a = rss(5); % Stable system with 5 eigs
e = esort(eig(a)); % Sort the eigenvalues with possibly complex entries
a.a = a.a - eye(5)*0.95*real(e(1)); % Make it closer to imaginary axis
[r,k] = rlocus(a); % Get the data without plotting
mydata = []; % To populate the data
for i=1:5
mydata(:,2*i -1) = (real(r(i,:))).'; % CL eig Real Part
mydata(:,2*i)    = (imag(r(i,:))).'; % CL eig Imag Part
end
mydata(:,11) = k'; % The gain array


Here I'm randomly creating a stable system and pushing the eigenvalues towards the imaginary axis (roughly) to get more critical systems. This will produce an 11 column data with the first 10 columns are the pole1 - pole5 real imaginary parts and last column is the gain selection matlab used to produce the plot.

You can either print mydata on the screen and copy, or save it as ASCII txt file. Here I copy pasted it because it is less hassle and root locus data is usually less than 100 rows. Then all you need is to use pgfplots to read and plot this data set. To do that I've also added a header row to the data for ease of access.

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.11}
pr1 pi1 pr2 pi2 pr3 pi3 pr4 pi4 pr5 pi5 k
-0.7949         0   -0.0444    3.9285   -0.0444   -3.9285   -0.9916    6.0362   -0.9916   -6.0362         0
-0.7190         0   -0.2172    4.2556   -0.2172   -4.2556   -1.1297    5.7959   -1.1297   -5.7959    1.0322
-0.7166         0   -0.2221    4.2680   -0.2221   -4.2680   -1.1351    5.7861   -1.1351   -5.7861    1.0818
-0.7142         0   -0.2269    4.2807   -0.2269   -4.2807   -1.1408    5.7761   -1.1408   -5.7761    1.1339
-0.7117         0   -0.2318    4.2937   -0.2318   -4.2937   -1.1467    5.7657   -1.1467   -5.7657    1.1885
-0.7093         0   -0.2366    4.3071   -0.2366   -4.3071   -1.1527    5.7550   -1.1527   -5.7550    1.2456
-0.7068         0   -0.2413    4.3209   -0.2413   -4.3209   -1.1590    5.7440   -1.1590   -5.7440    1.3056
-0.7043         0   -0.2460    4.3350   -0.2460   -4.3350   -1.1655    5.7326   -1.1655   -5.7326    1.3684
-0.7017         0   -0.2506    4.3495   -0.2506   -4.3495   -1.1723    5.7210   -1.1723   -5.7210    1.4342
-0.6991         0   -0.2551    4.3642   -0.2551   -4.3642   -1.1793    5.7090   -1.1793   -5.7090    1.5032
-0.6966         0   -0.2595    4.3794   -0.2595   -4.3794   -1.1866    5.6967   -1.1866   -5.6967    1.5755
-0.6940         0   -0.2637    4.3948   -0.2637   -4.3948   -1.1941    5.6840   -1.1941   -5.6840    1.6514
-0.6914         0   -0.2677    4.4105   -0.2677   -4.4105   -1.2019    5.6711   -1.2019   -5.6711    1.7308
-0.6887         0   -0.2715    4.4266   -0.2715   -4.4266   -1.2100    5.6578   -1.2100   -5.6578    1.8141
-0.6861         0   -0.2751    4.4429   -0.2751   -4.4429   -1.2185    5.6443   -1.2185   -5.6443    1.9014
-0.6835         0   -0.2784    4.4595   -0.2784   -4.4595   -1.2272    5.6305   -1.2272   -5.6305    1.9928
-0.6809         0   -0.2814    4.4763   -0.2814   -4.4763   -1.2363    5.6164   -1.2363   -5.6164    2.0887
-0.6783         0   -0.2841    4.4934   -0.2841   -4.4934   -1.2458    5.6021   -1.2458   -5.6021    2.1892
-0.6757         0   -0.2865    4.5107   -0.2865   -4.5107   -1.2556    5.5876   -1.2556   -5.5876    2.2945
-0.6731         0   -0.2885    4.5281   -0.2885   -4.5281   -1.2659    5.5729   -1.2659   -5.5729    2.4049
-0.6705         0   -0.2901    4.5456   -0.2901   -4.5456   -1.2765    5.5581   -1.2765   -5.5581    2.5207
-0.6679         0   -0.2913    4.5633   -0.2913   -4.5633   -1.2875    5.5432   -1.2875   -5.5432    2.6419
-0.6653         0   -0.2920    4.5809   -0.2920   -4.5809   -1.2990    5.5281   -1.2990   -5.5281    2.7690
-0.6628         0   -0.2923    4.5986   -0.2923   -4.5986   -1.3108    5.5131   -1.3108   -5.5131    2.9023
-0.6603         0   -0.2921    4.6162   -0.2921   -4.6162   -1.3231    5.4980   -1.3231   -5.4980    3.0419
-0.6578         0   -0.2915    4.6337   -0.2915   -4.6337   -1.3358    5.4831   -1.3358   -5.4831    3.1883
-0.6553         0   -0.2904    4.6511   -0.2904   -4.6511   -1.3489    5.4682   -1.3489   -5.4682    3.3417
-0.6529         0   -0.2888    4.6682   -0.2888   -4.6682   -1.3624    5.4535   -1.3624   -5.4535    3.5024
-0.6505         0   -0.2867    4.6851   -0.2867   -4.6851   -1.3762    5.4391   -1.3762   -5.4391    3.6709
-0.6481         0   -0.2842    4.7017   -0.2842   -4.7017   -1.3904    5.4249   -1.3904   -5.4249    3.8476
-0.6458         0   -0.2813    4.7179   -0.2813   -4.7179   -1.4048    5.4110   -1.4048   -5.4110    4.0327
-0.6435         0   -0.2780    4.7337   -0.2780   -4.7337   -1.4195    5.3975   -1.4195   -5.3975    4.2267
-0.6413         0   -0.2744    4.7490   -0.2744   -4.7490   -1.4344    5.3844   -1.4344   -5.3844    4.4301
-0.6391         0   -0.2704    4.7639   -0.2704   -4.7639   -1.4495    5.3716   -1.4495   -5.3716    4.6432
-0.6369         0   -0.2662    4.7783   -0.2662   -4.7783   -1.4647    5.3594   -1.4647   -5.3594    4.8666
-0.6348         0   -0.2618    4.7921   -0.2618   -4.7921   -1.4799    5.3476   -1.4799   -5.3476    5.1008
-0.6327         0   -0.2571    4.8055   -0.2571   -4.8055   -1.4951    5.3363   -1.4951   -5.3363    5.3462
-0.6307         0   -0.2524    4.8183   -0.2524   -4.8183   -1.5103    5.3254   -1.5103   -5.3254    5.6034
-0.6287         0   -0.2475    4.8306   -0.2475   -4.8306   -1.5254    5.3150   -1.5254   -5.3150    5.8730
-0.6267         0   -0.2426    4.8424   -0.2426   -4.8424   -1.5403    5.3051   -1.5403   -5.3051    6.1556
-0.6248         0   -0.2376    4.8536   -0.2376   -4.8536   -1.5552    5.2956   -1.5552   -5.2956    6.4517
-0.6230         0   -0.2326    4.8644   -0.2326   -4.8644   -1.5698    5.2866   -1.5698   -5.2866    6.7621
-0.6212         0   -0.2276    4.8746   -0.2276   -4.8746   -1.5842    5.2781   -1.5842   -5.2781    7.0875
-0.6194         0   -0.2226    4.8844   -0.2226   -4.8844   -1.5983    5.2699   -1.5983   -5.2699    7.4285
-0.6177         0   -0.2177    4.8937   -0.2177   -4.8937   -1.6122    5.2622   -1.6122   -5.2622    7.7859
-0.6161         0   -0.2129    4.9026   -0.2129   -4.9026   -1.6258    5.2548   -1.6258   -5.2548    8.1605
-0.6145         0   -0.2082    4.9111   -0.2082   -4.9111   -1.6390    5.2478   -1.6390   -5.2478    8.5531
-0.6129         0   -0.2035    4.9192   -0.2035   -4.9192   -1.6520    5.2412   -1.6520   -5.2412    8.9646
-0.6114         0   -0.1990    4.9269   -0.1990   -4.9269   -1.6646    5.2348   -1.6646   -5.2348    9.3960
-0.6099         0   -0.1946    4.9342   -0.1946   -4.9342   -1.6769    5.2289   -1.6769   -5.2289    9.8480
-0.6085         0   -0.1903    4.9412   -0.1903   -4.9412   -1.6889    5.2232   -1.6889   -5.2232   10.3219
-0.5731         0   -0.0850    5.0836   -0.0850   -5.0836   -1.9926    5.1104   -1.9926   -5.1104       Inf
}\mytable

\begin{document}

\begin{tikzpicture}[
%This is to provide the start  point cross marker
start marker/.pic={\draw (-#1,-#1) -- (#1,#1) (#1,-#1)--(-#1,#1);}
]
\begin{axis}[no marks,xmax=2,grid=both]% Don't put any markers, limit the visible area from one side ,draw grid
\foreach\x in{1,...,5}{% Iterate over the columns of the table
\addplot+[] table[x=pr\x,y=pi\x] {\mytable} % Draw the curves
node[draw,circle,inner sep=2pt] at (current plot end) {}%Put the ending marker with size adjusted to 2pt
pic at (current plot begin) {start marker=2pt};%Put the starting marker
}
\end{axis}
\end{tikzpicture}
\end{document}


I didn't use the gain column but if you want you can plot an individual row with markers to show a critical case.

For comparison this is matlab result; What a beauty! ;)

• Finally got to analyzing your example. Wow is it elegant! However, I'm having some problems compiling plus I want to format it a little differently so I'm hoping you can help me break it down. I see you are creating a table where the pairs of columns are the roots (real and imaginary) and then you are using those as X-Y locations to plot in the graph. That makes sense and I can see how to export out of matlab The actual drawing code I am getting confused about. – fubuloubu Nov 26 '14 at 21:47
• I tried to put specific parts of the code here, but I can't figure out how to get the Markdown working for it to make any sense – fubuloubu Nov 26 '14 at 21:50
• @BryantEisenbach I think that's my code. What exactly you have in mind? The markdown doesn't work in comment boxes. You can always edit your question and add more details. – percusse Nov 26 '14 at 21:57
• I don't understand what the 'point cross marker' is on the first line. I am getting an error when trying to compile on writeLaTeX to test. I see that you then have a loop that goes through the table and plots each root starting at the X's to the O's, which makes sense (and definitely reduces coding down!). However, I would like to format the axis ranges explicitly or at least more closely to how Matlab has it plotted, (-2.5:0.5 vs -8i:8i). – fubuloubu Nov 26 '14 at 21:59
• Sorry, still getting used to the StackExchange interface.... – fubuloubu Nov 26 '14 at 21:59

I will try to post in more detail when I can, but I can give you direction for now.

LaTeX + matplotlib is one of the best ways to get publication quality plots from data, since matplotlib plots can be saved as pgf code. I'll find out for sure, but I think it's scipy.signal that has some code for doing the basic things you need for a root locus (and other sorts of analysis on linear systems). It's been a while. If it isn't scipy, then there is a python package for basic controls and signals. I'll try to post a link to an iPython worksheet with an example.

Octave can produce root locus plots using exactly the same syntax as MATLAB. (You'll need the controls or signal processing toolboxes). But Octave uses GNUPLOT as the plotting back end, which has a TikZ terminal. I haven't done it this way before, but in theory, you should be able to futz around with Octave configurations so that it uses the tikz terminal rather than the default.

Lastly, there is a controls toolbox for Maxima, which I believe can also use GNUPLOT as a back end.