9

I wanted to know how I can go about plotting a simple bode magnitude transfer function in LaTeX.

This is the function that I would like to have the Magnitude response plotted:

enter image description here

Be aware that the Laplace variable s is a complex number j*frequency.

This is the response that I get from Matlab:

enter image description here

Here is what I have started with:

\documentclass[varwidth]{standalone}
\usepackage{tikz}
\usepackage{bodegraph}
\usetikzlibrary{calc}
\usepackage{pgfplots,siunitx}
\pgfplotsset{compat=1.12}

\begin{document}
\begin{tikzpicture}

\end{tikzpicture}
\end{document}
Joe
  • 9,080
  • 1
    You haven't started with anything but loading some packages and an empty environment... Some more code, please! (I can't help ou myself but someone else can probably.) – Svend Tveskæg Jan 07 '16 at 05:33
  • 4
    There is no trivial way to do what you want. One option is the bodegraph package or you could include some gnuplot code directly to use it with pgfplots. However I consider both options very "painful" and I'd rather export a text file from matlab with all the data and use the common plotting techniques of pgfplots. Reason: Latex cannot deal with complex numbers out of the box. – Robert Seifert Jan 07 '16 at 07:01
  • 6
    If you already have the result in matlab, why not just use matlab2tikz and pgfplots? – Ktree Jan 07 '16 at 12:48

3 Answers3

15

You can use de the bodegraph package (https://www.ctan.org/pkg/bodegraph)

http://www.texample.net/tikz/examples/bode-plot/

for your example

first : the plot of the amplitude and phase diagrams

\documentclass{article}
\usepackage{tikz}

\usepackage{bodegraph}

\begin{document}

\begin{tikzpicture}[xscale=15/4]
\begin{scope}[yscale=3/50]
\UnitedB
\semilog{0}{4}{-60}{60}

\BodeGraph[thick]{0:4}
{-\POAmp{1}{0.006}+
\SOAmp{1}{0.3}{100}}
\end{scope}
\begin{scope}[yshift=-7cm,yscale=3/90]
\UniteDegre
\OrdBode{15}
\semilog{0}{4}{-180}{90}
\BodeGraph[thick]{0:4}
{-\POArg{1}{0.006}+
\SOArg{1}{0.3}{100}}
\end{scope}
\end{tikzpicture}

\end{document}

enter image description here

second: with asymptotes

\documentclass{article}
\usepackage{tikz}

\usepackage{bodegraph}

\begin{document}

\begin{tikzpicture}[xscale=15/4]
\begin{scope}[yscale=3/50]
\UnitedB
\semilog{0}{4}{-60}{60}
\BodeGraph[thick,red]{0:4}
{-\POAmpAsymp{1}{0.006}+
\SOAmpAsymp{1}{0.3}{100}}
\BodeGraph[thick]{0:4}
{-\POAmp{1}{0.0006}+
\SOAmp{1}{0.3}{100}}
\end{scope}
\begin{scope}[yshift=-7cm,yscale=3/90]
\UniteDegre
\OrdBode{15}
\semilog{0}{4}{-180}{90}
\BodeGraph[thick,red]{0:4}
{-\POArgAsymp{1}{0.006}+
\SOArgAsymp{1}{0.3}{100}}
\BodeGraph[thick]{0:4}
{-\POArg{1}{0.006}+
\SOArg{1}{0.3}{100}}
\end{scope}
\end{tikzpicture}

\end{document}

enter image description here

third : decomposing the transfer function

\documentclass{article}
\usepackage{tikz}

\usepackage{bodegraph}

\begin{document}

\begin{tikzpicture}[xscale=15/4]
\begin{scope}[yscale=3/50]
\UnitedB
\semilog{0}{4}{-60}{60}
\BodeGraph[thick,red]{0:4}
{-\POAmp{1}{0.006}}
\BodeGraph[thick,green]{0:4}
{\SOAmp{1}{0.3}{100}}
\BodeGraph[thick]{0:4}
{-\POAmp{1}{0.006}+
\SOAmp{1}{0.3}{100}}
\end{scope}
\begin{scope}[yshift=-7cm,yscale=3/90]
\UniteDegre
\OrdBode{15}
\semilog{0}{4}{-180}{90}
\BodeGraph[thick]{0:4}
{-\POArg{1}{0.006}+
\SOArg{1}{0.3}{100}}
\BodeGraph[thick,red]{0:4}
{-\POArg{1}{0.006}}
\BodeGraph[thick,green]{0:4}
{\SOArg{1}{0.3}{100}}
\end{scope}
\end{tikzpicture}


\end{document}

enter image description here

You can also plot the Nichols plot with this package

\documentclass{article}
\usepackage{tikz}

\usepackage{bodegraph}
\begin{document}

\begin{tikzpicture}
\begin{scope}[xscale=6/180,yscale=8/60]

\BlackGraph*[samples=150,black,smooth,ultra thick]
{-1:3.5}{-\POArg{1}{0.006}+
\SOArg{1}{0.3}{100},-\POAmp{1}{0.006}+
\SOAmp{1}{0.3}{100}}
{[right]{$H_2 $}}
\BlackGrid
\end{scope}
\end{tikzpicture}

\end{document}

enter image description here

with "l'abaque de Black-Nichols"

\documentclass{article}
\usepackage{tikz}

\usepackage{bodegraph}
\begin{document}

\begin{tikzpicture}
\begin{scope}[xscale=6/180,yscale=8/60]

\BlackGraph*[samples=150,black,smooth,ultra thick]
{-1:3.5}{-\POArg{1}{0.006}+
\SOArg{1}{0.3}{100},-\POAmp{1}{0.006}+
\SOAmp{1}{0.3}{100}}
{[right]{$H_2 $}}
\AbaqueBlack
\StyleIsoM[blue,thick]
\IsoModule[2.3]
\BlackGrid
\end{scope}
\end{tikzpicture}

\end{document}

enter image description here

You can also plot the Nyquist plot

\documentclass{article}
\usepackage{tikz}

\usepackage{bodegraph}

\begin{document}


\begin{tikzpicture}
\begin{scope}[xscale=4,yscale=4]

\NyquistGraph[samples=150,black,smooth,ultra thick]
{-1:3.5}%
{-\POAmp{1}{0.006}+ \SOAmp{1}{0.3}{100}}%
{-\POArg{1}{0.006}+\SOArg{1}{0.3}{100}
}
\NyquistGrid

\end{scope}

\end{tikzpicture}

\end{document}

enter image description here

rpapa
  • 12,350
  • I wasn't not aware for this package. Good to know! – Zarko Jan 07 '16 at 16:03
  • you have to install gnuplot too – rpapa Jan 07 '16 at 16:04
  • Gnuplot is drawback for me ... I don't use it. However, your solution is really correct answer to OP question (so I up-vote it). It some how show, that some my assertion is not completely true. Obviously some one convert "mark-up-description-language, what (La)TeX in his original nature is, to something more.Looking different calculation packages and pgfmathengine this I should expected. – Zarko Jan 07 '16 at 16:15
  • 1
    @rpapa, Thanks for your elegant solution. Can you explain your choice for -\POAmp and \SOAmp and how that relates to my original equation? Thanks again! – Joe Jan 07 '16 at 17:33
  • 2
    POAmp FirstOrder Amplitude (in french First Order is Premier Ordre)

    if you want to plot $\frac{K}{1+\tau\cdot s}$ the command is \POAmp{K}{\tau}

    if you want $\frac{K}{1+\frac{2\cdot z}{\omega_n}\cdot s \frac{s^2}{\omega_n^}}$ the command is \SOAmp{K}{z}{\omega_n}

    – rpapa Jan 07 '16 at 19:40
  • this example http://www.texample.net/tikz/examples/bode-plot/ is good explanation for use the package – rpapa Jan 07 '16 at 19:47
6

Try:

\documentclass[border=3mm,
               tikz,
               preview
               ]{standalone}
\usepackage{pgfplots}
\pgfplotsset{width=8cm,compat=newest}

\begin{document}
    \begin{tikzpicture}
\begin{loglogaxis}[
title=Bode diagram,
xlabel={frequency},
ylabel={amplitude},
grid=major
                    ]
\addplot[domain=1:100000]  {(60*x+10000)/(x*x + 60*x+10000)};
\end{loglogaxis}
    \end{tikzpicture}
\end{document}

if this is what you looking for. In MWE is considered s as frekency (not complex frequency) and as variable is used default sign: x.

enter image description here

Edit: TikZ nor pgfplot are not capable directly plot complex function. For drawing them, you need to transform complex function in real one. In this particular case in magnitude (frequency) response and phase (frequency) response. In above solution is, let be emphasize (again) draw real function. (assuming that the formula present amplitude response). For complete Bode plot is missing diagram for phase response, however, for both is necessary to derive function from given formula (which assume "complex frequency")

Addendum: The question is, what is the question:

  • how to draw some function
  • or, how to derive some function, which you like to draw (in this particular case two real function from one complex).

I strongly believe, that SE is dedicated to the first problem, not to second.

Zarko
  • 296,517
  • Thanks for your input. I have updated my question with the plot of the transfer function derived from Matlab. How can I get this same response from tikz? – Joe Jan 07 '16 at 06:09
  • 1
    Of course. However, you need the same function description as is used in Matlab. I emphasize in answer, how the given function is considered. pgfplot will not convert it (as Matlab) in magnitude and phase response. This you shod do you for it. – Zarko Jan 07 '16 at 06:17
  • Thanks again! Can you direct me as to how to go about doing the conversion then? Sincerest thanks. – Joe Jan 07 '16 at 06:28
  • 1
    Hm, if you deal with transfer function, than I suppose, that you work with control (usually considered basic course electric engineering study) or with signals (also usually basic course), so you shod learn this. Otherwise, give google a chance to find anything about Bode plot (it gives ~ 478.000 results, may of them are materials from different universities). – Zarko Jan 07 '16 at 06:34
  • 1
    @Zarko unfortunately x is the complex number i*w - which Latex cannot deal with. You could use gnuplot though. – Robert Seifert Jan 07 '16 at 06:59
  • I aware of this, so I say in answer, that s is considered as real frequency. Consider x as complex frequency, the given formula should be transformed to amplitude (absolute value of it) and for phase part (ratio of imaginary versus real part of it) of plots. I suppose, that this should be clear so, I only show how to drive plot function. I'm not sure, that this forum is right one to give basic lessons about control or signal processing, or I'm wrong? I don't use gnuplot, so don't know anything about his capability to handle complex values. If you know, than please provide an answer! – Zarko Jan 07 '16 at 07:35
  • Unfortunately I don't know about gnuplot neither - at the point where I had to deal with that problem, I decided to stick with Matlab, rather than learing another programming language. – Robert Seifert Jan 07 '16 at 07:54
  • I just check pgfmath if it has support for complex function. So far I didn't find anything. SO, also from learning point of view, the correct wax is derive, \Re{f(s=\sigma+j\omega)}, \Im{f(s=\sigma+j\omega) and from them calculate magnitude (abs(f(s=\sigma+j\omega)) and phase (\frac{\Re{f(s)}}{\Im{f(s)}) and then them use as function in given answer. However, it seem, that many people (engineers?) expected, that all will do some computer instead of them ... This for sure doesn't lead to progress. – Zarko Jan 07 '16 at 08:10
  • @Zarko Every engineer should know what the computer does in that case. Your assumption is right, apart from that you usually can ignore the sigma part. I also did quite some research about how to do that in Latex, as it can't be done with pgfmath. The only way is to externalize the complex number calculations to another application, which could be everything. Gnuplot seems to be the only one (as far as I know) which can directly interact with Latex. Also: An very interesting way could be to use lua code+LuaLatex to include the calculations. But I don't have the time to work on a solution. – Robert Seifert Jan 07 '16 at 10:14
  • 3
    @Joe As you are already doing your calculations in MATLAB. Why not just export the calculated values to a csv file and plot these values with pgfplots? – Benjamin Jan 07 '16 at 12:44
  • For drawing point of view, yes. By this you can make good approximation of function. But, I will rephrase your opinion; why draw in TikZ and friends, if you can generate perfect plot (diagram) of function in Matlab, export them to eps or pdf picture and then simply include picture in LaTeX document with \includegraphics[...]{<myMatlabPicture>}? – Zarko Jan 07 '16 at 14:50
6

If its a one time thing, you can do it manually (the hard way). Odd powers contribute to imaginary part and even powers contribute to real part; with alternating signs. Now take the square root of the sum of the squares to get the magnitude of the complex number. Since you want the answer to be in dB you have to multiply by 20 after taking logarithm (the square root and the 20 partially cancel each other due to property of logarithms)updated bode.

The following is Zarko's answer modified.

\documentclass[border=3mm,
               tikz,
               preview
               ]{standalone}
\usepackage{pgfplots}
\pgfplotsset{width=8cm,compat=newest}

\begin{document}
    \begin{tikzpicture}
\begin{semilogxaxis}[
title=Bode diagram,
xlabel={frequency},
ylabel={amplitude},
grid=major,
xmax=10^4,
ymax=10]
\addplot[samples at={1,2,8,9,10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 140, 160, 200, 300, 400, 1000, 5000, 6000, 10000}]
{10 * log10( ( (60*x)^2         +(10000)^2 )/
                              ( (-x*x + 10000)^2 + (60*x)^2)
                           )};
\end{semilogxaxis}
    \end{tikzpicture}
\end{document}
AJN
  • 932
  • 1
    Section 89.3 Syntax for Mathematical Expressions: Functions in the manual lists ln, log10 and log2. – Torbjørn T. Jan 07 '16 at 12:51
  • 1
    Thanks!, I've updated my answer based on Torbjørn's answer. – AJN Jan 07 '16 at 13:17
  • @AJN, I can't resist to not comment: you made OP engineering homework (what I'm not willing to do, since otherwise he will never learn, how to do this ...), not only to show how to draw function. Nice solution! Almost equal result you can obtain width \addplot[domain=1:10000,samples=100] {...}. – Zarko Jan 07 '16 at 13:36
  • @Zarko That's not even engineering it's arithmetics. I don't think this online do your own homework stuff is a valid excuse to dismiss easy questions. – percusse Jan 07 '16 at 14:39
  • That didn't cross my mind(!) as i'm currently doing some control system related plotting myself (tikz-block-diagram). Anyway, more practice for me! Also, matlab+matlab2tikz() is my usual way of doing these things. – AJN Jan 07 '16 at 14:48
  • @AJN I used to have a complex numbers library for TikZ but then they switched to LuaLaTeX based computations (in newer libraries) so I think you can simply push all complex parts to Lua – percusse Jan 07 '16 at 16:21