How can I access the size of a tikzpicture's bounding box outside the tikzpicture?

I'm trying to calculate the size of a tikzpicture using the current bounding box, but every time I try to extract the coordinates I get 0pt (for everything).

\documentclass{article}
\usepackage{tikz}

\newlength{\mywidth}
\newlength{\myheight}

% computes width and height of tikzpicture

\newcommand{\pgfsize}[2]{ % #1 = width, #2 = height
\pgfextractx{#1}{\pgfpointdiff{\pgfpointanchor{current bounding box}{south west}}
{\pgfpointanchor{current bounding box}{north east}}}
\pgfextracty{#2}{\pgfpointdiff{\pgfpointanchor{current bounding box}{south west}}
{\pgfpointanchor{current bounding box}{north east}}}
}

\begin{document}

\noindent
\begin{tikzpicture}
\draw node[rotate=90]{
\framebox{
\begin{tabular}{c|c}
first column & second column\\
\hline
1 & A\\
2 & B\\
$\vdots$ & $\vdots$
\end{tabular}
}};
\draw[color=red] (current bounding box.south west) -- (current bounding box.north east);
\pgfsize{\mywidth}{\myheight}
\end{tikzpicture}

\noindent
Width = \the\mywidth \\
Height = \the\myheight
\end{document}


As you can see, one can draw a line across the bounding box, so it exists and is non-trivial. I'm thinking I may have to use \pgfgettransformentries, but when?

A. Ellet's comment is correct: it is a scope problem. Yes, \mywidth and \myheight are assigned a nonzero value within the scope of the tikzpicture environment, but, because those assignments are local, their value remains 0pt outside the scope of that environment.

You can fix the problem by making the assignments of \pgfsize's arguments global (rather than local) in the definition of that macro; see below. This post by Andrew Swan should also be of interest.

\documentclass{article}
\usepackage{tikz}
\show\pgfextractx

\newlength{\mywidth}
\newlength{\myheight}

% computes width and height of tikzpicture
\makeatletter
\newcommand{\pgfsize}[2]{ % #1 = width, #2 = height
\pgfextractx{\@tempdima}{\pgfpointdiff{\pgfpointanchor{current bounding box}{south west}}
{\pgfpointanchor{current bounding box}{north east}}}
\global#1=\@tempdima
\pgfextracty{\@tempdima}{\pgfpointdiff{\pgfpointanchor{current bounding box}{south west}}
{\pgfpointanchor{current bounding box}{north east}}}
\global#2=\@tempdima
}
\makeatother

\begin{document}

\noindent
\begin{tikzpicture}
\draw node[rotate=90]{
\framebox{
\begin{tabular}{c|c}
first column & second column\\
\hline
1 & A\\
2 & B\\
$\vdots$ & $\vdots$
\end{tabular}
}};
\draw[color=red] (current bounding box.south west) -- (current bounding box.north east);
\pgfsize{\mywidth}{\myheight}
\end{tikzpicture}

\noindent
Width = \the\mywidth \\
Height = \the\myheight
\end{document}

• I don't understand why juggling with \mytemplength. Just saying \global#1=#1 is exactly the same. But I'd use a scratch register such as \@tempdima: \pgfextractx{\@tempdima}{...}\global#1=\@tempdima that avoids the bad practice of using both local and global assignments to a variable. – egreg Oct 11 '13 at 15:48
• @egreg I used an intermediary variable because I though I would have trouble with recursion. Thanks for letting me know that my fears were unfounded. I'll improve my answer. – jub0bs Oct 11 '13 at 15:55
• If you say \let\mytemplength\mywidth and \mywidth is allocated the skip register 43 (as in your example), doing \show\mytemplength will output \mytemplength=\skip43 and you simply end up with \global\skip43=\skip43. – egreg Oct 11 '13 at 15:59
• @egreg Why skip register 43? What is so special about 43? – jub0bs Oct 11 '13 at 16:00
• When you say \newlength\mywidth, TeX allocates to \mywidth a skip register. It's 43 just because the last allocated skip register was number 42; but the number is of no concern for the end user: it may change if you load a new package, for instance; the important thing is that it's fixed during a run of (La)TeX. You find the allocated registers in the .log file. – egreg Oct 11 '13 at 16:04