I finally (!) got round to implementing this. Here's my code:
\documentclass{beamer}
% \url{http://tex.stackexchange.com/q/18704/86}
\usepackage{tikz}
\newcounter{jumping}
\resetcounteronoverlays{jumping}
\makeatletter
\tikzset{
stop jumping/.style={
execute at end picture={%
\stepcounter{jumping}%
\immediate\write\pgfutil@auxout{%
\noexpand\jump@setbb{\the\value{jumping}}{\noexpand\pgfpoint{\the\pgf@picminx}{\the\pgf@picminy}}{\noexpand\pgfpoint{\the\pgf@picmaxx}{\the\pgf@picmaxy}}
},
\csname jump@\the\value{jumping}@maxbb\endcsname
\path (\the\pgf@x,\the\pgf@y);
\csname jump@\the\value{jumping}@minbb\endcsname
\path (\the\pgf@x,\the\pgf@y);
},
}
}
\def\jump@setbb#1#2#3{%
\@ifundefined{jump@#1@maxbb}{%
\expandafter\gdef\csname jump@#1@maxbb\endcsname{#3}%
}{%
\csname jump@#1@maxbb\endcsname
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
#3
\pgfmathsetlength\pgf@x{max(\pgf@x,\pgf@xa)}%
\pgfmathsetlength\pgf@y{max(\pgf@y,\pgf@ya)}%
\expandafter\xdef\csname jump@#1@maxbb\endcsname{\noexpand\pgfpoint{\the\pgf@x}{\the\pgf@y}}%
}
\@ifundefined{jump@#1@minbb}{%
\expandafter\gdef\csname jump@#1@minbb\endcsname{#2}%
}{%
\csname jump@#1@minbb\endcsname
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
#2
\pgfmathsetlength\pgf@x{min(\pgf@x,\pgf@xa)}%
\pgfmathsetlength\pgf@y{min(\pgf@y,\pgf@ya)}%
\expandafter\xdef\csname jump@#1@minbb\endcsname{\noexpand\pgfpoint{\the\pgf@x}{\the\pgf@y}}%
}
}
\makeatother
\begin{document}
\begin{frame}
\begin{tikzpicture}[stop jumping]
\foreach \k in {1,...,7}
{
\fill<\k>[orange] (0,0) circle[radius=.5];
\fill<\k>[blue] (\k * 45:\k) circle[radius=.2] coordinate (a);
}
\draw (0,0) -- (a);
\end{tikzpicture}
\end{frame}
\end{document}
Here's how it works. We have a global counter, jumping
, which is stable under overlays. That is, beamer
implements overlays by reprocessing the code several times. Normally, each time through would lead to a counter being incremented, but so long as beamer
is told, it can take that into account and resets the counter for each run through. The upshot of this is that this counter can be used to label (in the non-TeXnical sense) tikzpicture
s in such a way that the different copies of the picture on different slides get the same label.
We use that label to save the bounding box of each version of the picture to the aux
file. We do this at the end of the picture to ensure that we get the right bounding box. When the aux
file is read in next time, it computes the maximum and minimum extends of the various bounding boxes for this picture and saves these as PGF points. Back in the picture, we use these computed points to adjust our bounding box to the maximum extent.
Some further remarks:
We save the bounding box of each picture before comparing it with the saved maximum. This means that the maximum is always computed on the actual sizes of the pictures and doesn't take into account any previous maximum. This means that it is sensitive to changes in the picture, which is how it should be.
The bounding box is adjusted by placing coordinates in the picture. This is to ensure that the picture doesn't jump around inside its box. Simply resetting the bounding box lengths would ensure that the picture took up the same amount of space on each slide, but not that the picture stayed in the same place in that box.
There are a few things that scaling doesn't affect; the most noticeable are node sizes and line widths. In a simple picture, it isn't hard to adjust the line width accordingly but the nodes can be difficult. It is possible to force a node to be scaled: put the scale option directly in the node's attributes. Thus \node[above,scale=0.6] at (8,11) {true};
would scale the node. This is a bit annoying to put on every node, so there's an every node
style that can be used to do this. Thus:
\begin{tikzpicture}[thick,scale=0.6, every node/.style={scale=0.6}]
Even so, you'd still have to remember to change two things each time here if you wanted to change the scale factor. Fortunately, there's a key transform shape
which means that the current transformation is applied to the node. The danger with using this is that this will also apply any rotations that happen to be in effect to the node (normally only translations are applied). If you don't have any rotations, then:
\begin{tikzpicture}[thick,scale=0.6, every node/.style={transform shape}]
will do just fine.
If you do have or worry about those rotations (or for anyone else interested) it would be simple to set a global scale
key to fix this:
\tikzset{global scale/.style={
scale=#1,
every node/.style={scale=#1}
}
}
Back to the "normal" solutions. Here's the various solutions:
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\framebox{\begin{tikzpicture}[thick]
\draw [dashed] (1,12) -- (11,12);
\node[above] at (4,11) {1}; \node[above] at (8,11) {true};
\end{tikzpicture}}
\framebox{\begin{tikzpicture}[thick, scale=0.6]
\draw [dashed] (1,12) -- (11,12);
\node[above] at (4,11) {1}; \node[above] at (8,11) {true};
\end{tikzpicture}}
\framebox{\begin{tikzpicture}[thick, transform canvas={scale=0.6}]
\draw [dashed] (1,12) -- (11,12);
\node[above] at (4,11) {1}; \node[above] at (8,11) {true};
\end{tikzpicture}}
\framebox{\begin{tikzpicture}[thick,scale=0.6, every node/.style={scale=0.6}]
\draw [dashed] (1,12) -- (11,12);
\node[above] at (4,11) {1}; \node[above] at (8,11) {true};
\end{tikzpicture}}
\framebox{\begin{tikzpicture}[thick,scale=0.6, every node/.style={transform shape}]
\draw [dashed] (1,12) -- (11,12);
\node[above] at (4,11) {1}; \node[above] at (8,11) {true};
\end{tikzpicture}}
\end{document}
I put the \framebox
s in because if you count carefully, you'll see that the third example isn't there! In fact, it ended up somewhere at the top of the page, outside what the standalone
package thought the page was. So it got clipped out.
![scaled pictures](https://i.stack.imgur.com/2HXMT.png)
Best Answer
I recommend to avoid using figure environments in beamer, because usually the figures are not intended to float in presentations, and they don't do it as Herbert commented. It can avoid confusion with floats in standard LaTeX. If you just use
figure
because you need captions, you could do it with the\captionof
command of thecaption
package instead.Here's an example, where a
minipage
of a small size.3\textwidth
is used together with a caption, and enlarged by\resizebox
to\textwidth
, the whole box including the caption is scaled.It would cause an error if
figure
with\caption
would be used here instead ofminipage
. Note, by using thecaption
package you can benefit from further features of this great package.