14

I have a tikzpicture,in this case a blue rectangle, that will produce a bounding box, here visualized by the green background. I would now like to place a node in the top left corner of the bounding box. In this case, since I know the absolute coordinates it is easy to do, but that is not always the case, especially when using external graphics or drawing three dimensional objects in rotated coordinate systems. It would therefore be handy, to be able to place the nodes relative to the bounding box. In the axis environment, nodes can be placed in relative coordinates using rel axis cs. In this case the code would be \node at (rel axis cs:0,1) [anchor=north west] {node content}. Since in my example, there is no pre-defined axis,this is not possible here. Is there something similar for a plain tikzpicture?

\documentclass[10pt,crop]{standalone}

\usepackage{tikz}

\usetikzlibrary{backgrounds}

\begin{document}

\begin{tikzpicture}[tight background,background rectangle/.style=
 {fill=green},show background rectangle] \path[draw=black,fill=blue]
 (0,-1) -- (-1,0) -- (1,2) -- (2,1) -- cycle; 
\end{tikzpicture}

\end{document}

enter image description here

Janek
  • 1,303
  • 1
  • 13
  • 33

1 Answers1

12

You can use current bounding box.north west with proper anchor. Since the bounding box will vary when we add something, it will be better to fix it by adding use as bounding box (thanks to zeroth). Then we are let loose to use all options like positioning library etc. A little example:

\documentclass[10pt,crop]{standalone}

\usepackage{tikz}

\usetikzlibrary{backgrounds,calc,positioning}

\begin{document}

\begin{tikzpicture}[tight background,background rectangle/.style= {fill=green},show background rectangle, ] 
\path[draw=black,fill=blue,use as bounding box] (0,-1) -- (-1,0) -- (1,2) -- (2,1) -- cycle;    %%% note the use as bounding box here
\node [draw,rectangle,inner sep=0pt,anchor=north west] at (current bounding box.north west)(me) {me};
\node [draw,rectangle,inner sep=0pt,anchor=north west,below=.7cm of me]  {me};
\node [draw,circle,inner sep=0pt,anchor=south] at ($(current bounding box.south east)+(-.5,.5)$) {you};
\end{tikzpicture}
\end{document}

enter image description here

Relative positioning can be done by making use of the available anchors of the bounding box. A simple demonstration will be:

\documentclass[10pt,crop]{standalone}

\usepackage{tikz}

\usetikzlibrary{backgrounds,calc,positioning}

\begin{document}

\begin{tikzpicture}[tight background,background rectangle/.style= {fill=green},show background rectangle, ] 
\path[draw=black,fill=blue,use as bounding box] (0,-1) -- (-1,0) -- (1,2) -- (2,1) -- cycle;    %%% note the use as bounding box here
\node [draw,rectangle,inner sep=0pt,anchor=north west] at (current bounding box.north west)(me) {me};
\node [draw,rectangle,inner sep=0pt,anchor=west] at ($(current bounding box.north west)!.37!(current bounding box.south west)$) {me};  %% 37% from north west
\node [draw,circle,inner sep=0pt,anchor=center] at ($(current bounding box.south)!.5!(current bounding box.east)$) {you};
\end{tikzpicture}
\end{document}

enter image description here

Also, please note the comment by zeroth below to disable the updating of bounding box.

  • Thanks, this solves the problem for my example. But, just out of interest, let's assume I would like to have the node at 63% height, is that possible, too? – Janek Jan 21 '13 at 14:49
  • 1
    the only problem with this approach is that the bounding box is not a fixed dimension size when creating the figure. Doing the 'me' node twice will not put it the same place. One could fix the bounding box with use as bounding box on a specific path. – nickpapior Jan 21 '13 at 14:49
  • 1
    This indeed is a problem. Using current bounding box.north west and after that current bounding box.south west will not place the nodes beneath each other. – Janek Jan 21 '13 at 14:53
  • @HarishKumar But then, unfortunately, we are back to the beginning of the question. If I have coordinates to specify a path as the bounding box, then I could use the same coordinates to place the nodes. I would not need to go the extra way using the bounding box. – Janek Jan 21 '13 at 15:03
  • 1
    @HarishKumar an easy fix is to make pgf not update the bounding box via this: \makeatletter \let\disablebbupdate\pgf@relevantforpicturesizefalse \let\enablebbupdate\pgf@relevantforpicturesizetrue \makeatother and insert \disablebbupdate right before the 'me' node. – nickpapior Jan 21 '13 at 15:24
  • Ok, so as for placing a node in the upper left corner of the bounding box without expanding it, the problem is solved. The only question, that remains is about more arbitrary positions of the node. In your example you use absolute values to shift the nodes. When the size of the rectangle is changed, so will the positions of the nodes relative to the rectangle. – Janek Jan 21 '13 at 15:35
  • @Janek I made an edit for relative positioning. But the options are some what limited here. –  Jan 21 '13 at 15:51
  • I like zeroth's most recent suggestion (particularly if made into an environment rather than a pair of commands), since it provides a way to re-enable updating of the bounding box. This is probably not relevant for this particular question, but could well be relevant in other situations. – Charles Staats Jan 21 '13 at 16:10
  • 4
    You can use overlay option or put content inside pgfinterruptboundingbox environment to avoid bounding box being updated. – percusse Jan 21 '13 at 16:11
  • @percusse yes, that was the environment, there had to be an environment for this! :) – nickpapior Jan 21 '13 at 18:22
  • Nice, all questions answered! Thank you all. – Janek Jan 22 '13 at 08:25