4

I'm trying to use a counter inside a TikZ picture, and use values resulting on calculations with this counter. Let's say for instance, I want i to be ranging from 0 to 9, j to be i*5 and k to be i*10. I've managed to get this working this way:

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\foreach \i in {0,...,9}
{
\def \j {\pgfmathparse{\i * 5}\pgfmathresult}
\def \k {\pgfmathparse{\i * 10}\pgfmathresult}
\node at (0, -\i) {\tiny \i,\j,\k};
}
\end{tikzpicture}
\end{document}

This works as I intend to, the output being:

0,0.0,0.0

1,5.0,10.0

2,10.0,20.0

3,15.0,30.0

4,20.0,40.0

5,25.0,50.0

6,30.0,60.0

7,35.0,70.0

8,40.0,80.0

9,45.0,90.0

Now, and this is where it gets tricky, I want to use the secondary counter, let's say j as a coordinate of the nodes:

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\foreach \i in {0,...,9}
{
\def \j {\pgfmathparse{\i * 5}\pgfmathresult}
\def \k {\pgfmathparse{\i * 10}\pgfmathresult}
\node at (0, \j) {\tiny \i,\j,\k};
}
\end{tikzpicture}
\end{document}

I end up with this error:

! Incomplete \iffalse; all text was ignored after line 9.
<inserted text> 
\fi 
<*> mwe.tex

Why doesn't it work? What would be the proper way to achieve what I want to do?

  • use \pgfmathsetmacro{\j}{\i*5} etc (untested) – daleif Mar 9 '17 at 15:15
8

Your attempt does not work because the \pgfmathparse{…}\pgfmathresult is not expanded until \j is used within the coordinate to the \node. TikZ, of course, does not expect this, so it fails to parse the coordinate. To fix this, you can expand the macros at definition time.

Here is, I believe, the most direct analogue of your code:

\documentclass[tikz]{standalone}

\begin{document}

\begin{tikzpicture}
  \foreach \i in {0,...,9} {
    \pgfmathparse{\i * 5}\edef\j{\pgfmathresult}
    \pgfmathparse{\i * 10}\edef\k{\pgfmathresult}
    \node at (0, \j) {\tiny \i,\j,\k};
  }
\end{tikzpicture}

\end{document}

This is a common pattern, so \pgfmathsetmacro provides a shortcut:

\documentclass[tikz]{standalone}

\begin{document}

\begin{tikzpicture}
  \foreach \i in {0,...,9} {
    \pgfmathsetmacro{\j}{\i * 5}
    \pgfmathsetmacro{\k}{\i * 10}
    \node at (0, \j) {\tiny \i,\j,\k};
  }
\end{tikzpicture}

\end{document}

Both yield the same result.

  • All the answers were great but your one does have the explanation I needed. Thanks. – nicoco Mar 10 '17 at 8:21
8

Not entirely sure why you get that, but use evaluate instead.

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\foreach [evaluate=\i as \j using \i*5,evaluate=\i as \k using \i*10] \i in {0,...,9}
{
\node at (0, \j) {\tiny \i,\j,\k};
}
\end{tikzpicture}
\end{document}
  • 2
    You could also have used \node at (0,\i*5) .... – Torbjørn T. Mar 9 '17 at 15:16
5

A solution using \pgfmathparse implicitly.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}[y=1mm]
\foreach \i in {0,...,9}
  \draw let \n1 = {5*\i}, \n2 = {10*\i} in
  (0, -\n1) node {\tiny \i,\n1,\n2};
\end{tikzpicture}
\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.