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.

Following Drawing on an image with TikZ, I've had many succesful instances of drawing on a picture with TikZ.

However, now I have a tikzpicture environment with several graphics, and I want to draw on each of them. However, it appears the solution offered by Drawing on an image with TikZ only works for pictures centred at (0, 0), because if I try to draw on my second picture, the coordinates do not behave as expected:

\documentclass[final, 12pt]{standalone}
\usepackage{tikz}
\newcommand{\helplines}[0]{
\draw[help lines,semithick,xstep=.1,ystep=.1] (0,0) grid (1,1);
\foreach \x in {0,1,...,9} { \node [anchor=north] at (\x/10,0) {0.\x}; }
\foreach \y in {0,1,...,9} { \node [anchor=east] at (0,\y/10) {0.\y}; }
}
\begin{document}%
\begin{tikzpicture}%
\node[anchor=south west,inner sep=0] (image1) at (0, 0)
    {\rule{3cm}{3cm}};
\begin{scope}[x={(image1.south east)},y={(image1.north west)}]
 % draw stuff
 %\helplines
\end{scope}
\node[anchor=south west,inner sep=0] (image2) at (image1.south east)
    {\rule{3cm}{3cm}};
\begin{scope}[x={(image2.south east)},y={(image2.north west)}]
 \helplines
 % draw more stuff, but coordinates do not map as desired
\end{scope}
\end{tikzpicture}
\end{document}

Result:

Not the desired effect

I'd like a transformed coordinate system with the origin at the bottom left at the picture and point (1, 1) at the upper right. This works for the picture located at (0, 0), but not for the image located immediately to the right. Why not, and how do I achieve the desired effect?

share|improve this question
    
Use scopes including the images and shift the scopes around via \begin{scope}[shift={(1,1)}]. Inside the scope (0,0) is always local. –  percusse Apr 4 '13 at 8:53
    
@percusse That solves it partially; it moves the origin appropriately, but (1, 1) does not yet refer to the upper right (it's still stretched). –  gerrit Apr 4 '13 at 8:58
    
Ah, it looks like it works if I additionally change x={(image2.south east)},... to x={(image1.south east)},.... Does that work because the images are equally sized? They are in my present example. I haven't tested with differently sized pictures. –  gerrit Apr 4 '13 at 9:01
    
You are missing an inner sep=0 for the first two nodes. Try \begin{tikzpicture}[inner sep=0,outer sep=0]. I am not sure what the final output is supposed to be so don't know if what I get is correct. –  Peter Grill Apr 4 '13 at 9:20
    
@PeterGrill The final output is supposed to be an environment where I can draw on either picture using local coordinates scaled so that (0, 0) is the lower left and (1, 1) is the upper right, as works for a single pictures in the linked question. –  gerrit Apr 4 '13 at 9:27

1 Answer 1

This is because you are scaling the unit vectors via x=... , y=.... but the argument of those in the second image are not orthogonal vectors. Because image2 is somewhere else and they are not (x0,0) and (0,y0) type of coordinates. Instead they are vectors with nonzero entries. That's why your coordinates are diagonal instead of horizontal/vertical.

To do the same you need to zero out the corresponding x or y components. Example

\documentclass[final, 12pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\newcommand{\helplines}[0]{
\draw[help lines,semithick,xstep=.1,ystep=.1] (0,0) grid (1,1);
\foreach \x in {0,1,...,9} { \node [anchor=north] at (\x/10,0) {\tiny .\x}; }
\foreach \y in {0,1,...,9} { \node [anchor=east] at (0,\y/10) {\tiny .\y}; }
}
\begin{document}%
\begin{tikzpicture}%
\node[anchor=south west,inner sep=0] (image1) at (0, 0)
    {\color{red}\rule{3cm}{3cm}};
\begin{scope}[x={(image1.south east)},y={(image1.north west)}]
 % draw stuff
 \helplines
\end{scope}
\node[anchor=south west,inner sep=0] (image2) at (image1.south east)
    {\color{blue}\rule{3cm}{3cm}};
\begin{scope}[
x={($(image2.north east)-(image2.north west)$)},
y={($(image2.north west)-(image2.south west)$)},
shift={(image2.south west)}]
 \helplines
 \end{scope}
\end{tikzpicture}
\end{document}

enter image description here

Here I've used the calc library to obtain the width and the height of the image. But you can avoid all of these by including the image also in the scope such that everything is locally defined identically. Then you shift those scopes around. Example:

\documentclass[tikz]{standalone}
\newcommand{\helplines}[0]{
\draw[help lines,semithick,xstep=.1,ystep=.1] (0,0) grid (1,1);
\foreach \x in {0,1,...,9} { \node [anchor=north] at (\x/10,0) {\tiny .\x}; }
\foreach \y in {0,1,...,9} { \node [anchor=east]  at (0,\y/10) {\tiny .\y}; }
}
\begin{document}%
\begin{tikzpicture}%
\node[anchor=south west,inner sep=0] (image1) at (0, 0)
    {\color{red}\rule{3cm}{3cm}};
\begin{scope}[x={(image1.south east)},y={(image1.north west)}]
 % draw stuff
 \helplines
\end{scope}

\begin{scope}[shift={(image1.south east)}] % Shift the scope

    \node[anchor=south west,inner sep=0] (image2) at (0,0) %still at the origin of this scope
        {\color{blue}\rule{3cm}{3cm}};
    \begin{scope}[x={(image2.south east)},y={(image2.north west)}]
     \helplines
    \end{scope}

\end{scope}
\end{tikzpicture}
\end{document}

this gives the identical output.

share|improve this answer

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.