TikZ 外部化、pgfplots 和动画

TikZ 外部化、pgfplots 和动画

我今天用 beamer 写了一个非常吸引人的演示文稿。它包括一个用该animate包制作的 pgfplot 动画,效果非常棒。问题是什么?我的一位同事想借用这个​​图来做一个用非 LaTeX 编写的演示文稿。此外,知道如何逐帧将动画 pgfplots 外部化以用于动画convertmencoder生成独立文件以包含在网站等中也很好。

自然,我转而externalize为他做这项工作。看来他们animate并不externalize同意……我该如何说服他们和好呢?

下面是一个大大简化的示例,供向导使用

\documentclass{standalone}
\usepackage{pgfplots}
\usepackage{animate}
% Comment out the following line to see what the plot looks like.
\usepgfplotslibrary{external}\tikzexternalize 

\begin{document}
%
\begin{animateinline}[controls]{10}
  \multiframe{30}{ind=0+1}{
    \begin{tikzpicture}
      \begin{axis}[ymin=-1, ymax=1, xmin=0, xmax=3.14]
        \addplot {sin(deg(x+\ind*pi/16))};
      \end{axis}
    \end{tikzpicture}
  }
\end{animateinline}
%
\end{document}

答案1

animate 包是否与 TeX 的 shipout 例程配合使用?外部库会替换它 —— 可能以不兼容的方式。

不过,下面的方法也有效:

\documentclass{article}
\usepackage{pgfplots}
\usepackage{animate}
% Comment out the following line to see what the plot looks like.
\usepgfplotslibrary{external}

\tikzexternalize


\begin{document}
%
\begin{animateinline}[controls]{10}
  \multiframe{30}{ind=0+1}{
    \tikzifexternalizing{%
        Work-around to make animate happy
    }{}%
    \begin{tikzpicture}
      \begin{axis}[ymin=-1, ymax=1, xmin=0, xmax=3.14]
        \addplot {sin(deg(x+\ind*pi/16))};
      \end{axis}
    \end{tikzpicture}
  }
\end{animateinline}
%
\end{document}

仅当转换其中一个帧时,该语句\tikzifexternalizing才成立。在这种情况下,只有感兴趣的图片才会进入输出 pdf - 我们可以安全地生成非空内容(并且动画包很开心)。

答案2

一体化方法

阅读评论,了解您是否需要在您的机器上安装 ImageMagick 和/或 FFMPEG。

\documentclass{article}

\usepackage{filecontents}

% create a parameterized template
\begin{filecontents*}{template.tex}
\documentclass[tikz,border=12pt]{standalone}
\usepackage{pgfplots}
\begin{document}
  \foreach \ind in {1,2,...,30}
    {
    \begin{tikzpicture}
      \begin{axis}[ymin=-1, ymax=1, xmin=0, xmax=3.14]
        \addplot[color=\clr]  {sin(deg(x+\ind*pi/16))};
      \end{axis}
    \end{tikzpicture}
  }
\end{document}
\end{filecontents*}


\usepackage{animate}

% creater a PDF file containing frames
%\def\param{red}
%\immediate\write18{pdflatex -jobname=frames "\def\noexpand\clr{\param} \noexpand\input{template}"}

% just another way with \unexpanded to save more keystrokes!
\def\param#1{%
\immediate\write18{\unexpanded{pdflatex -jobname=frames "\def\clr{#1} \input{template}"}}}
\param{blue}

% create a GIF animation (needs ImageMagick installed)
\immediate\write18{convert -delay 5 -loop 0 -density 100 -alpha remove frames.pdf frames.gif}

% create a list of PNG images, one for each frame (needs ImageMagick installed)
\makeatletter
\immediate\write18{convert -density 100 -alpha remove frames.pdf frames-\@percentchar02d.png}
\makeatother

% create a MP4 video (needs both ImageMagick and FFMPEG installed)
\makeatletter
\immediate\write18{convert -density 100 -alpha remove frames.pdf frames-\@percentchar02d.png}
\immediate\write18{ffmpeg -r 5 -i frames-\@percentchar02d.png -vcodec libx264 frames.mp4}
\makeatother

\begin{document}
% create a PDF animation
\begin{center}
    \animategraphics[controls,autoplay,loop,scale=1]{10}{frames}{}{}
\end{center}
\end{document}

GIF 输出

在此处输入图片描述

PNG 输出

我不会显示所有内容,因为它们会浪费你的带宽。

在此处输入图片描述

在此处输入图片描述

...

在此处输入图片描述

答案3

\usepgfplotslibrary{external}和包装animate不能很好地协同工作。

\tikzexternalizetikzpicture环境移到外部文件中以便单独处理(因此--shell-escape必须激活)并tikzpicture用 替换环境\includegraphics

第一次传递时,当没有外部 PDF 图形可用时,环境animateinline存储其所包含代码的框的大小为零。测量第一帧的框尺寸并相应地缩放动画小部件。当发现框为空时,animate有一个内置的停止条件。animate

为了解决这个问题,请考虑以下代码:

\documentclass{article}
\usepackage{pgfplots}
\usepackage{animate}
% Comment out the following line to see what the plot looks like.
\usepgfplotslibrary{external}

\newlength\mywidth
\newlength\myheight
\newsavebox\mybox
\begin{lrbox}{\mybox}
  \def\ind{0}%
  \begin{tikzpicture}
    \begin{axis}[ymin=-1, ymax=1, xmin=0, xmax=3.14]
      \addplot {sin(deg(x+\ind*pi/16))};
    \end{axis}
  \end{tikzpicture}
\end{lrbox}
\settowidth\mywidth{\usebox\mybox}
\settoheight\myheight{\usebox\mybox}

\tikzexternalize
\begin{document}
%
\begin{animateinline}[controls]{10}
  \multiframe{30}{ind=0+1}{
    \makebox[\mywidth][l]{\rule{0pt}{\myheight}%
      \begin{tikzpicture}
        \begin{axis}[ymin=-1, ymax=1, xmin=0, xmax=3.14]
          \addplot {sin(deg(x+\ind*pi/16))};
        \end{axis}
      \end{tikzpicture}%
    }
  }
\end{animateinline}
%
\end{document}

生成包含所有动画帧的独立且大小正确的多页 PDF 的简单方法是:

\documentclass{article}
\usepackage{pgfplots}
\usepackage{ifthen}
\usepackage[tightpage,active]{preview}
\PreviewEnvironment{tikzpicture}

\begin{document}
%
\newcounter{ind}%
\whiledo{\theind<30}{%
  \begin{tikzpicture}
    \begin{axis}[ymin=-1, ymax=1, xmin=0, xmax=3.14]
      \addplot {sin(deg(x+\theind*pi/16))};
    \end{axis}
  \end{tikzpicture}%
  \stepcounter{ind}%
  \newpage%
}
%
\end{document}

此多页 PDF 可以进一步转换为其他格式,例如 SWF:

pdf2swf frames.pdf
swfcombine -r10 --output frames10fps.swf --dummy frames.swf

相关内容