# Beamer overlays, tikz external and custom file name

This is a follow-up question from Use tikz external feature with beamer \only . Andrew's answer there is excellent, and does the job (almost) perfectly.

The rough edge I have found was when I tried to use \tikzsetnextfilename together with it.

Why would I want to do that? Because in beamer, one might need to reorder one's slides, or to add an overlay, etc. In this case, most pictures will need to be regenerated, even if they weren't changed.

What is the problem? The following M(n)WE shows the usual way of using \tikzsetnextfilename.

\documentclass{beamer}

\usepackage{tikz}

\usetikzlibrary{external}

\makeatletter
\tikzset{
beamer externalizing/.style={%
execute at end picture={%
\tikzifexternalizing{%
\ifbeamer@anotherslide
\pgfexternalstorecommand{\string\global\string\beamer@anotherslidetrue}%
\fi
}{}%
}%
},
external/optimize=false
}
\makeatother

\tikzset{every picture/.style={beamer externalizing}}

\tikzexternalize

\begin{document}

\begin{frame}
\tikzsetnextfilename{figure}
\only<1>{Image 1:}
\only<2>{Image 2:}
\begin{tikzpicture}
\only<1>{\node {Overlay 1};}
\only<2>{\node {Overlay 2};}
\end{tikzpicture}
\end{frame}

\end{document}


This doesn't work. I'm not pro enough with latex, beamer and tikz mechanics, but I suspect that the problem is tikz externalize trying to generate the two pictures with the same file name.

And indeed, the following code snippet does work.

\documentclass{beamer}

\usepackage{tikz}

\usetikzlibrary{external}

\makeatletter
\tikzset{
beamer externalizing/.style={%
execute at end picture={%
\tikzifexternalizing{%
\ifbeamer@anotherslide
\pgfexternalstorecommand{\string\global\string\beamer@anotherslidetrue}%
\fi
}{}%
}%
},
external/optimize=false
}
\makeatother

\tikzset{every picture/.style={beamer externalizing}}

\tikzexternalize

\begin{document}

\begin{frame}
\only<1>{\tikzsetnextfilename{figure-1}}
\only<2>{\tikzsetnextfilename{figure-2}}
\only<1>{Image 1:}
\only<2>{Image 2:}
\begin{tikzpicture}
\only<1>{\node {Overlay 1};}
\only<2>{\node {Overlay 2};}
\end{tikzpicture}
\end{frame}

\end{document}


Now it is still far from perfect. For example, it requires to know precisely how many overlays are needed for every picture.

Hence the question : is there a better, more natural way of achieving this? If not, is there a way to make this method transparent to the user (so that he doesn't need to count the overlays himself)?

## 1 Answer

You can automatically add the overlay number to the file name using the code from Accessing the current overlay number in beamer. If you only want to do this for some pictures, then use like:

  \tikzsetnextfilename{figure-\overlaynumber}


To add it to every picture you could make it part of the prefix:

\tikzexternalize[prefix=picture-\overlaynumber-]


Using the suffix notation, (\tikzset{external/figure name/.add={}{-\overlaynumber}}) doesn't seem to work as the figure name is overriden by the \tikzsetnextfilename. If you want to automatically add a suffix you'd have to hack \tikzsetnextfilename:

\let\orig@tikzsetnextfilename=\tikzsetnextfilename
\renewcommand\tikzsetnextfilename[1]{\orig@tikzsetnextfilename{#1-\overlaynumber}}


(inside the \makeatletter ... \makeatother bit).

Although the most hackish, this one ends up with the nicest file names so it's the one I've gone for.

\documentclass{beamer}
%\url{https://tex.stackexchange.com/q/119428/86}
\usepackage{tikz}

\usetikzlibrary{external}

\makeatletter
\newcommand*{\overlaynumber}{\number\beamer@slideinframe}
\tikzset{
beamer externalizing/.style={%
execute at end picture={%
\tikzifexternalizing{%
\ifbeamer@anotherslide
\pgfexternalstorecommand{\string\global\string\beamer@anotherslidetrue}%
\fi
}{}%
}%
},
external/optimize=false
}
\let\orig@tikzsetnextfilename=\tikzsetnextfilename
\renewcommand\tikzsetnextfilename[1]{\orig@tikzsetnextfilename{#1-\overlaynumber}}
\makeatother

\tikzset{every picture/.style={beamer externalizing}}

\tikzexternalize

\begin{document}

\begin{frame}
\tikzsetnextfilename{figure}
\only<1>{Image 1:}
\only<2>{Image 2:}
\begin{tikzpicture}
\only<1>{\node {Overlay 1};}
\only<2>{\node {Overlay 2};}
\end{tikzpicture}
\end{frame}

\end{document}

• Awesome, thank you! Note that it also offers a nice workaround to the "problem" you mentioned in the other question, that you need to regenerate all overlays for a picture in case one is changed (that is with the current CTAN version of tikz with the lazy up-to-date check, and assuming you force the regeneration by deleting the appropriate .pdf). – T. Verron Jun 16 '13 at 20:19
• This is very clever. Maybe it should be emphasized that the \overlaynumber command is not a native command, but is defined in the link given, to keep things together! – Mathias Kure Jun 14 '18 at 23:23
• This is a really good answer, unfortunately there seems to be some incompatibility with pgfplots when using gnuplot contour. For some reason, it appears that the contours get computed for every single overlay - even for frames that do not even contain them! (Cf. tex.stackexchange.com/q/522643/119955) Do you have any idea what going on there? – Hyperplane Jan 5 at 16:20
• @Hyperplane I'm afraid I have no experience with gnuplot contour so I've no idea what's going on there. It looks as though you have asked a new question about it, which is the best way to get new ideas. – Andrew Stacey Jan 5 at 20:43