TikZ-PGF – Avoid Recomputing Addplot in Beamer with Animate

animateanimationsbeamerpgfplotstikz-pgf

Using beamer and animate, is it possible to avoid recomputing some static expensive parts at each step?

MWE:

\documentclass[10pt]{beamer}
\usepackage{pgfplots}
\usepackage{animate}

\begin{document}
\begin{frame}{}

   \begin{animateinline}[controls,loop]{15} % frame rate
      \multiframe{10}{rt=0+0.04}{%

       \begin{tikzpicture}
         \begin{axis}[height=5cm,width=5cm]
            
            % some expensive static computation recomputed at each frame!
            \addplot[domain=0:1,samples=5000] ({cos(deg(2*pi*x))},{sin(deg(2*pi*x))});

            % the only animated part, unexpensive
            \node at (axis cs:0,0) {\rt};

        \end{axis}
      \end{tikzpicture}
    }
  \end{animateinline}
\end{frame}

\end{document}

Best Answer

The graph with axes is typeset once into an xlrbox (pkg xsavebox), while saving the label position and the lower left bounding box corner as named coordinates. Then, within the animation, a plain tikzpicture environment is used to place the saved graph and the animated label by means of TikZ nodes.

\documentclass[10pt]{beamer}

\usepackage{pgfplots}
\usepackage{animate}
\usepackage{xsavebox}

\begin{document}
\begin{frame}{}
  \begin{xlrbox}{Graph}
    \begin{tikzpicture}
      \begin{axis}[height=5cm,width=5cm]
         
         % some expensive static computation
         \addplot[domain=0:1,samples=5000] ({cos(deg(2*pi*x))},{sin(deg(2*pi*x))});

         % save label position
         \coordinate (label) at (axis cs:0,0);

      \end{axis}
      \coordinate (ll) at (current bounding box.south west);
    \end{tikzpicture}
  \end{xlrbox}%
%  
  \begin{animateinline}[controls,loop]{15} % frame rate
    \multiframe{10}{rt=0+0.04}{%
      \begin{tikzpicture}
        \node[inner sep=0pt, anchor=south west] at (ll) {\theGraph};
        \node at (label) {\rt};
      \end{tikzpicture}
    }
  \end{animateinline}
\end{frame}

\end{document}

xlrbox is used instead of the standard LaTeX lrbox as it greatly reduces the PDF file size (1/6 for 10 frames, 1/32 for 100 frames).

Extended example with multiple predefined label positions:

\documentclass[10pt]{beamer}

\usepackage{pgfplots}
\usepackage{animate}
\usepackage{xsavebox}
\usepackage{multido}

\begin{document}
\begin{frame}{}
  \begin{xlrbox}{Graph}
    \begin{tikzpicture}
      \begin{axis}[height=5cm,width=5cm]
         
         % define several labels
         \multido{\i=0+1,\rphi=90+-45}{8}{
           \pgfmathsetmacro{\xpos}{0.8*cos(\rphi)}
           \pgfmathsetmacro{\ypos}{0.8*sin(\rphi)}
           \edef\arg{ (label-\i) at (axis cs:\xpos,\ypos)}
           \expandafter\coordinate\arg;
         }

         % some expensive static computation
         \addplot[domain=0:1,samples=5000] ({cos(deg(2*pi*x))},{sin(deg(2*pi*x))});

      \end{axis}
      \coordinate (ll) at (current bounding box.south west);
    \end{tikzpicture}
  \end{xlrbox}%
%  
  \begin{animateinline}[controls,loop]{4} % frame rate
    \multiframe{8}{i=0+1,rphi=90+-45}{%
      \begin{tikzpicture}
        \node[inner sep=0pt, anchor=south west] at (ll) {\theGraph};
        \node at (label-\i) {$\rphi$};
      \end{tikzpicture}
    }
  \end{animateinline}
\end{frame}

\end{document}