2

The following code results in an error when introducing the foreach part. So, I would like to know what is wrong in it.

\documentclass[border=1cm]{standalone}
\usepackage{pgfplots}

\pgfplotsset{compat=newest,
poles/.style= { only marks, mark=x, mark size = 1ex, thick},
zeros/.style= { only marks, mark=o, mark size = 1ex, thick }
}

\begin{document} 
\begin{tikzpicture}
    \begin{axis}[axis lines=middle,
    xmax = 1, xmin = -8,
    xtick={1,...,-9},
    ymax = 2, ymin = -2,
    ytick={-2,...,2},
    ]
        \addplot[poles] coordinates {(-2,2) (-2,-2) (-8,0)};
        \addplot[zeros] coordinates {(-4,0)};
        \foreach \x/\y in {-2/2 , -2/-2 , -8/0 , -4/0 }{
        \node[label={180:{(\x,\y)}},inner sep=2pt] at (axis cs:\x,\y) {};
     }
    \end{axis}
\end{tikzpicture}
\end{document}

Additionally, how to remove the foreach code and replace it with a global setting of coordinates labeling inside pgfplotsset with a local input option of the angular placement instead of the fixed angle 180 provided in my code?

Diaa
  • 9,599

1 Answers1

2

Yes, this is one of the well-known expansion issue of pgfplots. Depending on how one views things, one may regard your question as a duplicate of the one that lead to this answer. If you feel it is a duplicate, I'll be happy to remove this answer. Otherwise just do

\documentclass[border=1cm]{standalone}
\usepackage{pgfplots}

\pgfplotsset{compat=newest,
poles/.style= { only marks, mark=x, mark size = 1ex, thick},
zeros/.style= { only marks, mark=o, mark size = 1ex, thick }
}

\begin{document} 
\begin{tikzpicture}
    \begin{axis}[axis lines=middle,clip=false,%<-added
    xmax = 1, xmin = -8,
    xtick={1,...,-9},
    ymax = 2, ymin = -2,
    ytick={-2,...,2},
    ]
        \addplot[poles] coordinates {(-2,2) (-2,-2) (-8,0)};
        \addplot[zeros] coordinates {(-4,0)};
        \foreach \x/\y/\z in {-2/2/-90 , -2/-2/90 , -8/0/90 , -4/0/90 }{
        \edef\temp{\noexpand\node[label={\z:{(\x,\y)}},inner sep=2pt] at (axis
        cs:\x,\y) {};}
        \temp
     }
    \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

Why is that necessary? pgfplots runs a "survey phase" before it actually typesets things. And during this phase it can, in a way, forget things inside loops because there is another expansion magic taking place. For that reason, pgfplots comes with its own loop mechanism like \pgfplotsinvokeforeach and \pgfplotsforeachungrouped, see section 8.1 of the manual for more detail. My personal bottomline is to try out the above trick first, and if it works, then I am fine with it. ;-)

ADDENDUM: Here is an ugly version that allows you to add the anchors via point meta. (I have not much time now.) It works, but you can only have the anchors between 0 and 360, i.e. say -90 won't work. And there is an empty plot. The reason for this is that I have not the time now to find out how to do a better \pgfplotspointmetatransformed conversion.

\documentclass[border=1cm]{standalone}
\usepackage{pgfplots}

\pgfplotsset{compat=newest,
poles/.style= { scatter,
        scatter src=explicit, only marks, mark=x, mark size = 1ex, thick},
zeros/.style= { scatter,
        scatter src=explicit, only marks, mark=o, mark size = 1ex, thick }
}
\newcommand\myparse[1]{\pgfmathparse{#1}\typeout{\pgfmathresult}}
\begin{document} 
\begin{tikzpicture}
    \begin{axis}[axis lines=middle,clip=false,%<-added
    xmax = 1, xmin = -8,
    xtick={1,...,-9},
    ymax = 2, ymin = -2,
    ytick={-2,...,2},
    visualization depends on=x \as \rawx,
    visualization depends on=y \as \rawy,
    visualization depends on=\pgfplotspointmetatransformed \as \mymeta,
    nodes near coords style={
                anchor=(\pgfplotspointmetatransformed/1000)*360
            },
    nodes near coords={(\pgfmathprintnumber{\rawx},\pgfmathprintnumber{\rawy})},
    ]
        \addplot[poles,forget plot,opacity=0] coordinates {(0,0)[0] (0,0)[360]};
        \addplot[poles] coordinates {(-2,2)[90] (-2,-2)[270] (-8,0)[0]};
        \addplot[zeros] coordinates {(-4,0)[270]};
    \end{axis}
\end{tikzpicture}
\end{document}

enter image description here

  • Thanks for your answer. Could you please consider my second question of replacing this code snippet of foreach with more global setting inside pgfplotsset with optional argument of angular position instead of the fixed 180? – Diaa Nov 20 '18 at 19:11
  • @Diaa I updated my answer but do not precisely understand what you mean by " how to remove the foreach code...". Of course, you could define a pgfkey with some default value, but this won't eliminate the need for a loop (as far as I understand the problem) and be a little bit of an overkill IMHO. –  Nov 20 '18 at 19:23
  • Sorry for not explaining well enough. Do you mean that if I want to assign the angle manually for every single coordinate label I need to use foreach? If yes, can I embed the foreach inside any defined style or key? For example, can I have something like \addplot[poles, label style = {angle1 , angle2 , angle3} ] coordinates {(-2,2) (-2,-2) (-8,0)};, and if I didn't set this key value (i.e. \addplot[poles, label style]) , the label is printed at a preset default angle? – Diaa Nov 20 '18 at 19:44
  • 1
    @Diaa The closest thing I am aware of is to add "meta data" in square brackets after the coordinates. See p. 47 of the manual. This "meta data" is usually some color, but it can be an angle some nodes near coords get rotated by with the usual visualization depends on key. –  Nov 20 '18 at 19:51
  • I appreciate your explanation. I would be highly grateful if you considered showing me how to do it (or something close to it) using nodes near coords. Thanks – Diaa Nov 20 '18 at 20:01
  • 1
    @Diaa I added something, but do not have the time now to make it more elegant. –  Nov 20 '18 at 20:41
  • I highly appreciate your consideration to help me with this. Have a nice day :) – Diaa Nov 20 '18 at 20:51
  • @Diaa I got really stuck when trying to make this more elegant, and I ended up asking a follow-up question. –  Nov 21 '18 at 16:10
  • That's interesting. In case you are curious enough :), you might want to check my other relevant question. – Diaa Nov 21 '18 at 16:15