3

I want a symbol written above each coordinate, which is taken from a table with a "label" column.

At first I wanted to just use \node[above] at (axis cs:\x, \y){\Label} but this causes a not obvious error, most likely related to the \Label expansion. The command \addplot+ coordinates {(\x, \y)} node[above] {Something}; with the text of the node Something works, but as soon as I put inside the node a command that is defined from a table element, I get a non-obvious error.

! Undefined control sequence. \pgfplotsretval -> node[above] {\Label } l.39

At the same time, \addplot understands the coordinates macro...

% !TeX program = pdflatex % !TeX encoding = utf8 \documentclass{standalone} \usepackage{pgfplots} \usepackage{pgfplotstable} \begin{document} \pgfplotstableread{ x y label 4 0.511 e 5 2.2 u 6 4.7 d 7 96 s 8 105.7 mu 9 1270 c 10 1777 tau 11 4180 b 12 173000 t }\loadedtable \begin{tikzpicture} \begin{semilogyaxis} \foreach \row in {0,...,8} { \pgfplotstablegetelem{\row}{x}\of\loadedtable \let\x=\pgfplotsretval \pgfplotstablegetelem{\row}{y}\of\loadedtable \let\y=\pgfplotsretval \pgfplotstablegetelem{\row}{label}\of\loadedtable \let\Label=\pgfplotsretval \addplot+ coordinates {(\x, \y)} node[above] {\Label}; } \end{semilogyaxis} \end{tikzpicture} \end{document} 
2
  • Why do you think you need a loop? Commented Mar 15 at 19:17
  • Data may appear or disappear in the table Commented Mar 15 at 19:17

2 Answers 2

4

There is no problem with \let. But \foreach stores the \node instruction as is, and when the picture is delivered at \end{tikzpicture}, what you get as coordinates is (\x,\y) for each one of them, but \x and \y have no longer a meaning.

Solution: \expanded.

\foreach \row in {0,1,...,8} { \pgfplotstablegetelem{\row}{x}\of\loadedtable \let\x\pgfplotsretval \pgfplotstablegetelem{\row}{y}\of\loadedtable \let\y\pgfplotsretval \pgfplotstablegetelem{\row}{label}\of\loadedtable \let\Label\pgfplotsretval \expanded{\noexpand\node[above] at (\x, \y) {$\Label$};} } 

output

3

The answer turned out to be a compilation of already known solutions. The tikz macros inside \foreach need to wrapped in \edef\temp{\noexpand ...}\temp tags.

% !TeX program = pdflatex % !TeX encoding = utf8 \documentclass{standalone} \usepackage{pgfplots} \pgfplotsset{compat=1.18} \usepackage{pgfplotstable} \begin{document} \pgfplotstableread{ x y label 4 0.511 e 5 2.2 u 6 4.7 d 7 96 s 8 105.7 mu 9 1270 c 10 1777 tau 11 4180 b 12 173000 t }\loadedtable \begin{tikzpicture} \begin{semilogyaxis} \addplot table[x=x, y=y] \loadedtable; \foreach \row in {0,1,...,8} { \pgfplotstablegetelem{\row}{x}\of\loadedtable \edef\x{\pgfplotsretval} \pgfplotstablegetelem{\row}{y}\of\loadedtable \edef\y{\pgfplotsretval} \pgfplotstablegetelem{\row}{label}\of\loadedtable \edef\Label{\pgfplotsretval} \edef\temp{ \noexpand\node[above] at (\x, \y) {$\Label$}; } \temp } \end{semilogyaxis} \end{tikzpicture} \end{document} 
2
  • 2
    The fact that \let works is surprising... probably due to some expansion magic. Much better if you use \edef\x{\pgfplotsretval} and so on. And you do not need axis cs: if you add the (suggested by the package) \pgfplotsset{compat=1.18} Commented Mar 15 at 19:33
  • 1
    @Rmano Yes, thank you. I took that into account Commented Mar 15 at 19:41

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.