4

I want to plot a Bode diagram and show the phase margin using tikz intersections.
Here is what I have done:

 \documentclass{article}
 \usepackage[utf8]{inputenc}
 \usepackage[european]{circuitikz}
 \usepackage{tikz}
    \usetikzlibrary{shapes, calc, intersections}
 \usepackage{pgfplots}
 \pgfplotsset{compat=1.14}
    \usetikzlibrary{pgfplots.groupplots}
 \usepackage{siunitx}
 \usepackage{amsmath}
 \usepackage{amssymb}
 \usepackage{amsfonts}
 \usepackage{subcaption}
 \renewcommand*{\j}{\mathrm{j}}
 \begin{document}
 \begin{figure}[h]
        \begin{tikzpicture}[trim axis right, remember picture]
            \begin{semilogxaxis}[
                name=mag,
                width=\linewidth,
                height=0.5\linewidth,
                ylabel=$20\log_{10}\left(|H\!(\j2\pi f)\right|)$,
                %xlabel=$f\,/\,\si{\Hz}$,
                xmin=1000, xmax=1e10,
                grid=both, minor grid style=dotted, minor y tick num = 4,
                xticklabels={}]

            \addplot [thick, name path=mag] table[x=Magnitude X, y=Magnitude Y, col sep=comma] {bode.csv};
            \draw[red, thick, name path=0dB] (axis cs:1e3,0) -- (axis cs:1e10,0);
            \end{semilogxaxis}

            \begin{semilogxaxis}[
                name=phase,
                at={($(mag.south) - (0,0.05\linewidth)$)},
                anchor=north,
                width=\linewidth,
                height=0.5\linewidth,
                xmin=1000, xmax=1e10,
                xlabel=$f\,/\,\si{\Hz}$,
                ylabel=$\arg\{H(\j2\pi\omega)\}$,
                grid=both, minor grid style=dotted, minor y tick num = 4]

                \addplot [thick, name path= phase] table[x=Phase X, y=Phase Y, col sep=comma] {bode.csv};
                \draw[red, thick, name path= PM] (axis cs:1e3,0) -- (axis cs: 1e10,0) coordinate (pmend);
            \end{semilogxaxis}
            \path [draw, name intersections={of=mag and 0dB,by={intmag}}, name path=vertical] (intmag) coordinate (IM) -- (IM|-phase.south);
            \draw [latex-latex, name intersections={of=vertical and PM, by={intpm}}] (intpm) -- (intpm|-pmend) node[midway, left] {$PM$};
        \end{tikzpicture}
        \caption{Closed-loop Bode plot without Miller compensation}
    \end{figure}
    \end{document}

This is my result. enter image description here Which is wrong. It should look something similar to the pink lines in this picture. enter image description here I think the issue with my code has to do with the coordinate system being used outside and inside the axis environment which causes the result to be wrong.
How can I fix it?
Thanks

PD: csv file here

jagjordi
  • 794

1 Answers1

3

Thanks for your update. The perhaps simplest way to go is to extract the x value of the intersection in the upper plot and to use it in the lower plot to get the second intersection. See also this answer for why your intersections got moved.

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.14}
\usepgfplotslibrary{groupplots,fillbetween}
\usepackage{siunitx}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsfonts}
\usepackage{subcaption}
\renewcommand*{\j}{\mathrm{j}}
\begin{document}
\begin{figure}[h]
\begin{tikzpicture}[trim axis right, remember picture]
 \begin{groupplot}[group style={group size=1 by 2,
  horizontal sep=0pt,vertical sep=12pt},%disabledatascaling,
  height=0.5\linewidth,width=\linewidth,xmode=log, ymode=normal]
    \nextgroupplot[
%        name=mag,
        ylabel=$20\log_{10}\left(|H\!(\j2\pi f)\right|)$,
        %xlabel=$f\,/\,\si{\Hz}$,
        xmin=1000, xmax=1e10,
        grid=both, minor grid style=dotted, minor y tick num = 4,
        xticklabels={}]

    \addplot [thick, name path=mag] table[x=Magnitude X, y=Magnitude Y, col sep=comma] {bode.csv};
    \draw[red, thick, name path=0dB] (axis cs:1e3,0) -- (axis cs:1e10,0);
    \path [name intersections={of=mag and 0dB,by={intmag}}]
    (intmag) \pgfextra{\pgfplotspointgetcoordinates{\pgfpointanchor{intmag}{center}}
    \xdef\myx{\pgfkeysvalueof{/data point/x}}\typeout{\myx}};
    \nextgroupplot[
        name=phase,
        xmin=1000, xmax=1e10,
        xlabel=$f\,/\,\si{\Hz}$,
        ylabel=$\arg\{H(\j2\pi\omega)\}$,
        grid=both, minor grid style=dotted, minor y tick num = 4]

   \addplot [thick, name path global=phase] table[x=Phase X, y=Phase Y, col sep=comma] {bode.csv};
   \draw[red, thick, name path global=PM] (axis cs:1e3,0) -- (axis cs: 1e10,0) coordinate (pmend);
   \path[name path=vert] (\myx,0) coordinate(low) -- (\myx,200);
   \path [name intersections={of=vert and phase,by={vertPM}}];
 \end{groupplot}
 %\path [draw,name path=vertical] (intmag) coordinate (IM) -- (IM|-phase.south);
 \draw (intmag) -- (low);
 \draw [latex-latex] (low) -- (vertPM) node[midway, left] {$PM$};
\end{tikzpicture}
\caption{Closed--loop Bode plot without Miller compensation.}
\end{figure}
\end{document}

enter image description here

  • Thanks for your answer, unfortunately it is not what I wanted. I updated the picture that shows the result I expect. I want a line from the point the first plot crosses the red line that goes down to the second red line. Then I want arrows from the point that vertical line crosses the second plot to the red line. Thanks again – jagjordi Dec 17 '18 at 13:22
  • Hi again. Your code runs perfectly using Live TeX 2018 but I just tried to use it in Overleaf and it gives an error. Here is a dump of the log. I don't understand the error. Thank you for your help! – jagjordi Dec 18 '18 at 00:34
  • @jagjordi I have not really an idea, but it seems that there is a problem with lualatex. The code above does not require lualatex. Can you tell overleaf to compile with pdflatex instead? If not, the other thing you can try to do is to use your original code and use the way to extract the coordinates from my answer? I switched to group plots because it is more elegant and because of the problems with shift reported here. (I do not fully agree with the answer to this question, though.) –  Dec 18 '18 at 02:42
  • I am using pdfLaTeX as compiler. Why do you think it is using lualatex? – jagjordi Dec 18 '18 at 10:03
  • I tried what you suggested, using my original code but your method for extracting the coordinates and it keeps failing. I suspect the issue is in this line \path [name intersections={of=mag and 0dB,by={intmag}}] (intmag) \pgfextra{\pgfplotspointgetcoordinates{\pgfpointanchor{intmag}{center}} \xdef\myx{\pgfkeysvalueof{/data point/x}}\typeout{\myx}}; – jagjordi Dec 18 '18 at 11:08
  • @jagjordi You may be right, but I do not see that, Which part of the error message makes you suspect this? (It is true, though, that the /data point/x requires version 1.16, at least this is how I read this post. Which version do you have on overleaf?) –  Dec 18 '18 at 22:58
  • It's not the error message. I just tried removing everything and adding it again line by line and it fails after I add that line. How can I check the version that overleaf uses? – jagjordi Dec 18 '18 at 23:37
  • I just tried using compat=1.16 and it says maximum allowed is 1.15. That would explain the issue. Is there any way to modify your solution so it doesn't use that conflicting command? – jagjordi Dec 18 '18 at 23:39
  • @jagjordi I guess that would essentially amount to copying the relevant part of the new pgfplots package to the preamble of the document. To me it would sound much more reasonable if overleaf would use the latest version. It is out for 9 months now, and it fixes issues of previous versions. Do you know what their reason is not to update? (I could understand if they wait one month, but 9?) –  Dec 18 '18 at 23:52