# Position TikZ node relative to bounding box of overall picture

I would like to draw some points in TikZ, and position them relative to the bounding box of the overall picture. Specifically, I would like to give their y-coordinate explicitly, and have their x-coordinate taken from the left-edge of the picture's bounding box. How can I do this?

Here is an example. Each time I invoke \myCircle or \mySquare, the circle/square is drawn, and a little "notch" is drawn on the left-hand side. (The purpose of the notch is to be a drawing aid, so users can see where shapes are positioned.) The y-coordinate of the notch is taken from the centre of the circle/square. The x-coordinate is currently fixed at 0, but I would prefer that to be something like bounding box of overall picture.west.

\documentclass[border=5mm]{standalone}
\usepackage{tikz}

\newcommand\myCircle[2]{%
\fill[red] (#1,#2) circle (5);
\draw (-2,#2) -- (0,#2);
}
\newcommand\mySquare[2]{%
\fill[red] (#1-5,#2-5) rectangle (#1+5,#2+5);
\draw (-2,#2) -- (0,#2);
}

\begin{document}
\begin{tikzpicture}[x=1mm,y=1mm]
\myCircle{7}{5}
\mySquare{26}{0}
\myCircle{8}{20}
\end{tikzpicture}
\end{document}


-
One problem is that you won't know the bounding box until the very end of the picture. So I would store the y values in a list and then iterate over that list at the very end of the picture (using execute at end picture). –  Andrew Stacey Jun 3 '13 at 10:17

A possibility is to create labeled local bounding boxes for referencing later for each path.

\documentclass{article}
\usepackage{tikz}
\newcount\mycircle
\newcount\mysquare

\newcommand\myCircle[2]{%
\begin{scope}[local bounding box/.expanded=c\the\mycircle]
\draw[red] (#1,#2) circle (5);
\end{scope}
}
\newcommand\mySquare[2]{%
\begin{scope}[local bounding box/.expanded=s\the\mysquare]
\draw[red] ({#1-5},{#2-5}) rectangle ({#1+5},{#2+5});
\end{scope}
}

\tikzset{every picture/.style={
execute at end picture={
\ifnum\the\mycircle>0\relax%
\foreach\myc in{1,...,\the\mycircle}{%
\draw[overlay] (current bounding box.north west |- c\myc) -- ++(-3mm,0);%
}%
\fi%
\ifnum\the\mysquare>0\relax%
\foreach\myc in{1,...,\the\mysquare}{%
\draw[overlay] (current bounding box.north west |- s\myc) -- ++(-3mm,0);%
}%
\fi%
\mycircle=0\mysquare=0%
}
}
}
\begin{document}
\begin{tikzpicture}[x=1mm,y=1mm]
\myCircle{0}{5}
\mySquare{26}{0}
\myCircle{8}{20}
\mySquare{10}{-3}
\end{tikzpicture}

\vspace{2cm}

\begin{tikzpicture}[x=1mm,y=1mm]
\myCircle{-1}{5}
\myCircle{3}{7}
\end{tikzpicture}
\end{document}


-
Hmm, I might have read the question wrong. So the point is not drawing the notches I guess... –  percusse Jun 4 '13 at 21:25
I’d additionally through in a \pgftransformreset so that the notches are not affected by any transformation (scaling/rotation). –  Qrrbrbirlbel Jun 4 '13 at 23:34
@JohnWickerson I thought notches are just indicators but the geometric shapes should have been placed only by referring to their x coordinate. But now I see that it doesn't make sense too. I guess it's me the problem. I need coffee. –  percusse Jun 5 '13 at 8:59

I ended up using a simplified version of percusse's answer, following Andrew's suggestion to keep just a list of y-coordinates. The code is below. I'd just like to point out two "gotchas" that gave me confusing error messages:

• If A and B are nodes, you can use A |- B to calculate the coordinate with A's x-value and B's y-value. You might expect to be able to write the pair (x,y) instead of A or B, but note the following gotcha: The syntax is (A |- x,y) not (A |- (x,y)).

• Be careful when using \x or \y as the iterating variable of a \foreach loop. In the code below, it would be fine, but in an earlier version I used let \p1 = (oldBBox.north west), instead of the |- syntax, to store the top-left point of the bounding box in \x1,\y1. This is a problem if the variables \x and \y are already in use.

## Code

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\gdef\ys{}

\makeatletter
\newcommand*\snoc[2]{%
\ifx#1\@empty
\xdef#1{#2}
\else
\xdef#1{#1,#2}
\fi
}
\makeatother

\newcommand\myCircle[2]{%
\draw[red] (#1,#2) circle (5);
\snoc\ys{#2}
}
\newcommand\mySquare[2]{%
\draw[red] ({#1-5},{#2-5}) rectangle ({#1+5},{#2+5});
\snoc\ys{#2}
}

\tikzset{every picture/.style={
execute at end picture={
\coordinate (oldBBox) at (current bounding box.north west);
\foreach \yvalue in \ys {%
\draw (oldBBox |- 0,\yvalue) -- ++(-3mm,0);
}
\gdef\ys{}
}
}}

\begin{document}
\begin{tikzpicture}[x=1mm,y=1mm]
\myCircle{0}{5}
\mySquare{26}{0}
\myCircle{8}{20}
\mySquare{10}{-3}
\end{tikzpicture}

\vspace{2cm}

\begin{tikzpicture}[x=1mm,y=1mm]
\myCircle{10}{5}
\myCircle{3}{7}
\end{tikzpicture}
\end{document}

-