Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Here's something mystifying: I've been trying to use a for loop to create several copies of essentially the same picture stacked vertically on top of one another. But when I use \pgfmathresult in the yshift value, it puts all copies of the picture in the same spot - essentially it acts as if \pgfmathresult evaluates to 0 regardless of what the actual result of the computation is. It's probably best illustrated by this MWE:

\documentclass{article}
\usepackage{tikz}

\begin{document}
  \begin{tikzpicture}
    \foreach \i in {1,...,4} {
      \pgfmathparse{2*\i}
      \begin{scope}[yshift=\pgfmathresult cm]
        \fill (0,0) circle(3pt);
      \end{scope}
    }
  \end{tikzpicture}
\end{document}

The weird thing is that if I change yshift to xshift, the copies of the picture are spread out horizontally as I would expect. Is there some reason for this behavior, or is it a bug?

share|improve this question
    
This is likely the same problem as, for example, here: tex.stackexchange.com/questions/9988/… or tex.stackexchange.com/questions/10258/…. –  Caramdir Mar 8 '11 at 4:22
    
Side remark: you should be able to just write [yshift=2*\i cm]. –  Caramdir Mar 8 '11 at 4:24
    
@Caramdir: okay, I didn't recognize either of those as the same problem. I thought the fact that it worked with xshift but not yshift suggested some deeper explanation. –  David Z Mar 8 '11 at 4:51
    
And re: the side remark, the actual calculation is going to be something like 75*(\i - 1) pt, which doesn't work when I put it directly in yshift. –  David Z Mar 8 '11 at 4:53
    
@David: Yes you are right but It's preferable to never use \pgfmathresultdirectly. I think it's a good way to avoid this and in this case you have three solutions : you can avoid the use of a scope and the use of pgfmathresult, you can use shift and not yshift like Frédéric or you can use \pgfmathsetmacro –  Alain Matthes Mar 8 '11 at 5:01

2 Answers 2

up vote 6 down vote accepted

The better solution is :

\documentclass{article}
\usepackage{tikz}

\begin{document}
  \begin{tikzpicture}
    \foreach \i in {1,...,4} {
        \draw[yshift=2*\i cm,fill] (0,0) circle(3pt);
    }
  \end{tikzpicture}
\end{document}

but

It's always a good way to stock the \pgfmathresult in a personal macro or to use \pgfmathsetmacro

\documentclass{article}
\usepackage{tikz}

\begin{document}
  \begin{tikzpicture}
    \foreach \i in {1,...,4} {
      %\pgfmathparse{2*\i}
      \pgfmathsetmacro{\myshift}{2*\i} 
      \begin{scope}[yshift=\myshift cm]
        \fill (0,0) circle(3pt);
      \end{scope}
    }
  \end{tikzpicture}
\end{document} 

now with 75*(\i - 1), Caramdir's remark is fine, we can use 75*(\i - 1)*1pt

\documentclass{article}
\usepackage{tikz}    
\begin{document}
  \begin{tikzpicture}
    \foreach \i in {1,...,4} {
        \draw[yshift=75*(\i - 1)* 1 pt,fill] (0,0) circle(3pt);
    }
  \end{tikzpicture}      
\end{document} 
share|improve this answer
    
Is there a reason not to use \pgfmathsetmacro{\myshift}{2*\i} in your second example? –  Caramdir Mar 8 '11 at 5:59
    
@Caramdir: No you are right but I would like to keep the David's code. I updated my answer and you last remark is fine about *1pt –  Alain Matthes Mar 8 '11 at 6:13

I find that using shift={(x,y)}]is less prone to unwanted effects (I don't know why this is). In your case, you should write

\documentclass{article}
\usepackage{tikz}

\begin{document}
  \begin{tikzpicture}
    \foreach \i in {1,...,4} {
      \pgfmathparse{2*\i}
      \begin{scope}[shift={(0,\pgfmathresult)}]
        \fill (0,0) circle(3pt);
      \end{scope}
    }
  \end{tikzpicture}
\end{document}

The result is then exactly what you are looking for :

enter image description here

share|improve this answer
    
The shift={(x,y)} is more "stable" because it reads the value as coordinate which is then parsed, but xshift and yshift await a simple dimension. In the first case you can use numbers without units. –  Martin Scharrer Mar 8 '11 at 8:21

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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