Having the \begin{lrbox}
etc within a frame
makes it local to the frame
, hence it cannot be recalled later, unless defining a globallrbox
environment and using that instead. Such a definition might be done by
\usepackage{etoolbox}
\usepackage{letltxmacro}
\LetLtxMacro{\globallrbox}{\lrbox}
\LetLtxMacro{\endgloballrbox}{\endlrbox}
\patchcmd{\globallrbox}{\setbox}{\global\setbox}{}{\showtokens{patching globallrbox failed}}
The figure numbers will be different because the \caption
command is responsible for assigning the numbers, and you have two \caption
commands. Probably trying to put the whole figure
environment within a box is not going to be easy (and you can't put the caption
in the box without the figure
environment either), and does not allow you to append the text "(again)" to the caption the second time, so better to fiddle with the labels/counters, as I have done below, extending the example to show the effect on having other figures in between.
In the following I have avoided using the globallrbox
environment and moved the lrbox
outside of the frame to better illustrate the various approaches. You could probably tidy this up further by providing additional macros/environments for saving and recalling figures.
\documentclass{beamer}
\usepackage{tikz}
\setbeamertemplate{caption}{{\small\bfseries\MakeUppercase{\insertcaptionname~\insertcaptionnumber}}\quad\insertcaption}
\newsavebox{\myfigurebox}
\makeatletter
\newcommand*{\localsetcounter}[2]{% same as LaTeX's \setcounter, but removed the \global
\@ifundefined {c@#1}{\@nocounterr {#1}}%
{\csname c@#1\endcsname #2\relax}%
}
\newcommand*{\reusefigurecounter}[1]{%only use this within your figure environment to keep the changes local to that environment, and before the \caption command!
\localsetcounter{figure}{\getrefnumber{#1}}%
\let\refstepcounter\@gobble
}
\makeatother
\setcounter{errorcontextlines}{\maxdimen}
\begin{document}
\begin{lrbox}{\myfigurebox}% the lrbox is outside any frames, but after \begin{document} so that the right fonts and things are set up, and before we first want to use it
\centering
\begin{tikzpicture}
\draw (0,0) -- ++(75:1 cm) -- ++(-75:1 cm);
\end{tikzpicture}
\end{lrbox}
\begin{frame}{First Frame}
\begin{figure}
\usebox{\myfigurebox}
\caption{Description.}
\label{myfigure}
\end{figure}
Some text.
\end{frame}
\begin{frame}{Another Frame}
\begin{figure}
something else
\caption{Description.}
\end{figure}
Some text.
\end{frame}
\begin{frame}{Other Frame}
\begin{figure}
\centering
\usebox{\myfigurebox}
\reusefigurecounter{myfigure}
\caption{Description (again).}
\end{figure}
More text.
\end{frame}
\begin{frame}{Another Frame}
\begin{figure}
something else entirely
\caption{Description.}
\end{figure}
Some text.
\end{frame}
\end{document}
Update: slightly better interface?
With this version, use a savefigure
environment anywhere before you want the first copy of that figure to appear, providing a label in the first argument by which to recall it later.
The figure is then called up or recalled with either the \figurefirstuse
or \reusefigure
command, depending whether it has been shown already or not. The arguments to these commands are the label name and the caption, which need not be the same for all recalls of the same image. It does not currently save any previously used caption(s) automatically.
Not sure if all this stuff is necessary or elegant, but seems to work, now also when there are overlays. Note that there are some limitations with regards to error handling at the very least. It is not easy to automatically determine if the figure is being used for the first time or not because beamer
resets the figure
counter when it reprocesses the frame for multiple slides (ie overlays and pauses), hence I have given up on trying to do that for now.
There is also a figureandsave
environment which saves the figure and shows it in the same place, internally calling the above commands. Takes the same arguments as for \figurefirstuse
in this case.
I have left the previous version above as it may be clearer what's actually going on. The following example should hopefully illustrate the new interface better than my description of it.
\documentclass{beamer}
\usepackage{tikz}
\setbeamertemplate{caption}{{\small\bfseries\MakeUppercase{\insertcaptionname~\insertcaptionnumber}}\quad\insertcaption}
\makeatletter
\newcommand*{\localsetcounter}[2]{% same as LaTeX's \setcounter, but removed the \global
\@ifundefined {c@#1}{\@nocounterr {#1}}%
{\csname c@#1\endcsname #2\relax}%
}
\newcommand*{\reusefigurecounter}[1]{%#1=label, only use this within your figure environment to keep the changes local to that environment, and before the \caption command!
\localsetcounter{figure}{\getrefnumber{#1}}%
\let\refstepcounter\@gobble
}
\usepackage{etoolbox}
\usepackage{letltxmacro}
\LetLtxMacro{\globallrbox}{\lrbox}
\LetLtxMacro{\endgloballrbox}{\endlrbox}
\patchcmd{\globallrbox}{\setbox}{\global\setbox}{}{\showtokens{patching globallrbox failed}}
\newenvironment{figureandsave}[2]{% parameters #1=label name,#2=caption
\def\currsavefigurecaption{#2}%
\def\currsavefigurename{#1}%
\begin{savefigure}{#1}}%
{\end{savefigure}%
\figurefirstuse{\currsavefigurename}{\currsavefigurecaption}%
}
% can use savefigure within or outside of a frame, but always after \begin{document}
\newenvironment*{savefigure}[1]{% parameters #1=label name
\expandafter\newbox\expandafter{\csname savedfigure#1box\endcsname}%use \newbox instead of \newsavebox as we have to allow beamer to process the same figure multiple times if a frame contains multiple slides
\begin{globallrbox}{\csname savedfigure#1box\endcsname}%
}
{\end{globallrbox}}
% use \figurefirstuse the first time you want to show the figure
\newcommand\figurefirstuse[2]{% parameters #1=label name,#2=caption
\@ifundefined{savedfigure#1box}{\errmessage{figure #1 hasn't been saved yet}}{%
% calling this multiple times for the same figure will result in it having multiple numbers assigned to it and multiply defined label issues
\begin{figure}%
\usebox{\csname savedfigure#1box\endcsname}%
\caption{#2}%
\label{savedfigure#1}%
\end{figure}}}
% use \reusefigure if the figure has already been shown, and you want to show it again
\newcommand\reusefigure[2]{% parameters #1=label name, #2=new caption
\@ifundefined{savedfigure#1box}{\errmessage{figure #1 hasn't been saved yet}}{%
% no easy way to test if the figure has been used or not yet, but will be numbered Figure 0 if not!
\begin{figure}%
\usebox{\csname savedfigure#1box\endcsname}%
\reusefigurecounter{savedfigure#1}%
\caption{#2}%
\end{figure}}}
\makeatother
\begin{document}
\begin{savefigure}{test}
World.
\end{savefigure}
\begin{frame}{First Frame}
\begin{figureandsave}{myfigure}{Description.}
\centering
\begin{tikzpicture}
\draw (0,0) -- ++(75:1 cm) -- ++(-75:1 cm);
\end{tikzpicture}
\end{figureandsave}
\pause
Some text after a pause.
\end{frame}
\begin{frame}{In between}
\begin{figure}
A different figure
\caption{For testing}
\end{figure}
\pause
\figurefirstuse{test}{Hello}
\reusefigure{test}{Hello again}
\end{frame}
\begin{frame}{Other Frame}
\reusefigure{myfigure}{Description (again).}
\begin{figure}
A second figure on the same frame.
\caption{With a number}
\end{figure}
More text.
\end{frame}
\end{document}
There are at least two relatively simple options: beamer's \againframe
(section 11.2 of the manual), or manipulating the figure counter:
\documentclass{beamer}
\setbeamertemplate{caption}[numbered]
\begin{document}
\begin{frame}[label=A]
The original frame
\begin{figure}
\centering
\includegraphics[width=0.5\textwidth]{example-image-a}
\caption{\label{fig:example}Caption}
\end{figure}
\end{frame}
\begin{frame}
A second frame
\begin{figure}
\centering
\includegraphics[width=0.5\textwidth]{example-image-b}
\caption{Caption}
\end{figure}
\end{frame}
\againframe{A}
\begin{frame}
A third frame
\begin{figure}
\centering
\includegraphics[width=0.5\textwidth]{example-image-c}
\caption{Caption}
\end{figure}
\end{frame}
\begin{frame}
A slightly different frame with a repeated image from the first frame
% Ref: http://www.latex-community.org/forum/viewtopic.php?f=5&t=809
\begin{figure}
\centering
\includegraphics[width=0.5\textwidth]{example-image-a}
\renewcommand\thefigure{1}
\caption{Caption}
\addtocounter{figure}{-1}
\end{figure}
\end{frame}
\begin{frame}
A fourth frame
\begin{figure}
\centering
\includegraphics[width=0.5\textwidth]{example-image-b}
\caption{Caption}
\end{figure}
\end{frame}
\end{document}

Best Answer
To achieve numbering of figures, you need to set: