I am doing a beamer
presentation with animated tikzpicture
environments. In the MWE, the top figure consists of a plot which never changes and a point moving on it. Since the plot is long to compile, I saved it in a file image.pdf
which I load in a node
. Unfortunately, I did not find a way of loading the image once for all: my current solution is to load it at every step (i.e. about 600 times…).
The bottom plot consists of a curve drawn by \pgfplots
from a data file data.dat
. I have 5 different data files (I use the same one in the MWE) which are loaded one after the other using only
. For one data file, I am plotting an animated point on the curve. Again, I did not found another solution that plotting the curve at every iteration (i.e. about 600 times…).
In total, the compilation takes several minutes. I reduced the number of iterations so that the provided code should take about 20 seconds.
So, there are my questions:
-
How can I load the image once for all in the top plot?
-
How can I plot each of the five curves once for all in the bottom plot?
-
Are there clumsinesses in the code which I would not have spotted?
I tried to move the animateinline
and multiframe
within in tikzpicture
, causing the error:
File ended while scanning use of \beamer@collect@@body.
Code:
\documentclass{beamer}
\usepackage{tikz}
\usepackage{pgfplots,pgfplotstable}
\usepackage{animate}
\pgfplotstableread[header=false]{
1.733 1.770 1.807 1.843 1.880 1.918
}\mytable
\begin{document}
\begin{frame}{Title}
% Data to read [a single file "data.dat" is used here for simplification purposes]
\only<1>{\pgfplotstableread[col sep=space,row sep=newline,header=true]{./data.dat}\datatable\def\indice{5}}
\only<2>{\pgfplotstableread[col sep=space,row sep=newline,header=true]{./data.dat}\datatable\def\indice{4}}
\only<3>{\pgfplotstableread[col sep=space,row sep=newline,header=true]{./data.dat}\datatable\def\indice{3}}
\only<4>{\pgfplotstableread[col sep=space,row sep=newline,header=true]{./data.dat}\datatable\def\indice{2}}
\only<5>{\pgfplotstableread[col sep=space,row sep=newline,header=true]{./data.dat}\datatable\def\indice{1}}
% Get number of rows
\pgfplotstablegetrowsof{\datatable}
\pgfmathsetmacro{\rows}{int(\pgfplotsretval-1)}
\begin{center}
\begin{animateinline}[loop,poster=first]{10}
\multiframe{201}{i=0+1}{%
% Get last value of first column of data.dat
\pgfplotstablegetelem{\rows}{[index]0}\of\datatable%
\pgfmathsetmacro{\tmax}{\pgfplotsretval}%
% Get x-coordinate of moving point
\pgfplotstablegetelem{0}{[index]\indice}\of\mytable%
\pgfmathsetmacro{\tfirst}{\pgfplotsretval}%
\begin{tikzpicture}
% top plot
\begin{axis}[%
scale only axis,
axis on top,
width=4cm, height=2.25cm,
xmin=1.5, xmax=2.2,
ymin=0.3, ymax=1.5,
]
% LOADS IMAGE AT EVERY STEP!
\node[anchor=south west,inner sep=0pt] at (axis cs:1.5,0.3) {\includegraphics[width=4cm, height=2.25cm]{./image}};
\addplot[mark=*,red] coordinates {(\tfirst,\tmax-\tfirst)};
\end{axis}
% bottom plot
\begin{scope}[shift={(0,-4.3)}]
\begin{axis}[every axis legend/.append style={nodes={right}},
scale only axis,
width=5.025cm,height=3.15cm,
enlarge x limits={value=0.02,upper},
enlarge y limits=false,
xlabel={$x$}, ylabel={$y$}
]
\pgfplotstablegetelem{\i}{[index]0}\of{\datatable}\let\time\pgfplotsretval
\pgfplotstablegetelem{\i}{[index]\indice}\of{\datatable}\let\position\pgfplotsretval
\addplot[mark=*,blue] coordinates {(\time,\position)};
% PLOTS HOLE CURVE AT EVERY STEP!!
\addplot [thick,blue] table [x index=0, y index=\indice] {\datatable};
\end{axis}
\end{scope}
\end{tikzpicture}%
}
\end{animateinline}
\end{center}
\end{frame}
\end{document}
Link to data.dat
: hosted on filedropper
Link to image.pdf
: hosted on filedropper or to Original on Overleaf
Link to the complete project (can be downloaded as zip): hosted on overleaf
Best Answer
The static part of the whole
tikzpicture
, i. e. the top image with axes and the bottom plotted curve plus axes & axis labels can be saved into a PDF XObject using thexsavebox
package.The
tikzpicture
thus saved can be inserted as a background image while plotting on its top the isolated red and moving blue dots to create the animation frames.Unlike inserting standard saveboxes, referencing PDF-XObject-based saveboxes does not replicate the saved code inside the PDF output file.
A few additions were necessary to the original code of the question:
The
axis
optionfor the background and when plotting the isolated dots, and
when plotting the isolated dots.
The axis ranges must be determined from the input data, because they must be set as axis options when plotting the single dots.
Furthermore, the bounding box lower left coordinate of the background plot needs to be saved into TeX macros for correct placement of the background node in the animation frames.
Compilation times and PDF file sizes with the original data sets (5 x 201 data points) and the original -->
image.jpg
<--To see the isolated dots, enable
and change
to