我正在尝试将 外化pgfplots
,gnuplot
并将contour gnuplot
内化beamer
。为此,我正在使用visible on=<>
的功能\usetikzlibrary{overlay-beamer-styles}
(参见这个答案按用户丹尼尔)以及自动编号解决方案来自用户循环空间。
我创建了一个由 3 个框架组成的 MWE,每个框架包含 3 张幻灯片,其中包含(A)原始 pgfplots(B)gnuplots(C)轮廓 gnuplots。
预期行为:当外部化时,比如说第二帧的图像,其他帧上的图像应该被忽略。
实际行为:在每个叠加层中都会计算轮廓图。总共计算了 81 组轮廓图。如果删除前 2 帧(不包含轮廓图),则仍会计算 27 组轮廓图。
如何修复此错误?
\documentclass{beamer}
\usepackage{tikz, pgfplots}
\pgfplotsset{compat=1.16}
\usepgfplotslibrary{external}
\usetikzlibrary{overlay-beamer-styles}
% automatic beamer numbering
%\url{https://tex.stackexchange.com/q/119428/86}
\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[only named=true]
\begin{document}
\begin{frame}{pgfplots}
\tikzsetnextfilename{pgfplots}
\begin{tikzpicture}
\begin{axis}
\addplot[visible on=<1-3>] {x};
\addplot[visible on=<2-3>] {exp(x)};
\addplot[visible on=<3-3>] {x*x};
\end{axis}
\end{tikzpicture}
\end{frame}
\begin{frame}{gnuplot}
\tikzsetnextfilename{gnuplot}
\begin{tikzpicture}
\begin{axis}
\addplot[visible on=<1-3>] gnuplot{x};
\addplot[visible on=<2-3>] gnuplot{exp(x)};
\addplot[visible on=<3-3>] gnuplot{x*x};
\end{axis}
\end{tikzpicture}
\end{frame}
\begin{frame}{gnuplot contour}
\tikzsetnextfilename{contour}
\begin{tikzpicture}
\begin{axis}[view={0}{90}, domain=-2:2]
\addplot3[visible on=<1-3>,contour gnuplot={draw color=red,number=20, labels=false}] {x};
\addplot3[visible on=<2-3>,contour gnuplot={draw color=blue,number=20, labels=false}] {y};
\addplot3[visible on=<3-3>,contour gnuplot={draw color=black,number=20, labels=false}] {x^2+y^2};
\end{axis}
\end{tikzpicture}
\end{frame}
\end{document}
答案1
消除这些额外轮廓图的最简单方法是使用\only
而不是visible on=<>
键。这样,图表只会在指定的幻灯片上生成(使用visible on=<>
,它们会在所有幻灯片上生成,但只会显示在选定的幻灯片上)。
\begin{axis}[view={0}{90}, domain=-2:2]
\addplot3[visible on=<1-3>,contour gnuplot={draw color=red,number=20, labels=false}] {x};
\only<2-3>{\addplot3[contour gnuplot={draw color=blue,number=20, labels=false}] {y};}
\only<3>{\addplot3[contour gnuplot={draw color=black,number=20, labels=false}] {x^2+y^2};}
\end{axis}
去除在外部化框架时生成的轮廓图,在其他框架上绘制图比较棘手,但可行。我在另一个问题中添加了此问题的解决方案 (看这里)。
下面是一个完整的 MWE,它结合了两种解决方案,只生成 10 个contourmpX.table
文件并且编译速度更快。
\documentclass{beamer}
\usepackage{tikz, pgfplots}
\pgfplotsset{compat=1.16}
\usepgfplotslibrary{external}
\usetikzlibrary{overlay-beamer-styles}
% automatic beamer numbering
%\url{https://tex.stackexchange.com/q/119428/86}
\makeatletter
\newcommand*{\overlaynumber}{\number\beamer@slideinframe}
\tikzset{
beamer externalizing/.style={%
execute at end picture={%
\tikzifexternalizing{%
\ifbeamer@anotherslide
\pgfexternalstorecommand{\string\global\string\beamer@anotherslidetrue}%
\fi
}{}%
}%
},
every picture/.style={beamer externalizing}
}
% remove the `-\overlaynumber` suffix from the jobname
% the name is stored in `\job@no@suffix` and the number in `\job@suffix@number`
\def\strip@suffix#1{%
\begingroup%
\edef\@tempa{#1-}%
\expandafter\endgroup%
\expandafter\@strip@suffix\@tempa\relax%
}
\def\@strip@suffix#1-#2\relax{%
\ifx\relax#2\relax%
\edef\job@suffix@number{#1}%
\def\next{\relax}%
\else%
\expandafter\ifx\expandafter\relax\job@no@suffix\relax%
\def\job@no@suffix{#1}%
\else%
\edef\job@no@suffix{\job@no@suffix-#1}%
\fi%
\def\next{\@strip@suffix#2\relax}%
\fi%
\next%
}
% check if the next tikzpicture is the to-be-externalized one
% or has the same basename and precedes it
\def\if@is@current@pic#1{%
\begingroup%
\def\job@no@suffix{}%
\strip@suffix\pgfactualjobname%
\ifnum\job@suffix@number<\overlaynumber\relax%
\def\job@no@suffix{}%
\fi%
\edef\current@pic@basename{#1}%
\edef\current@pic@basename{%
\expandafter\detokenize\expandafter{\current@pic@basename}%
}%
\ifx\job@no@suffix\current@pic@basename%
\expandafter\endgroup\expandafter\@firstoftwo%
\else%
\expandafter\endgroup\expandafter\@secondoftwo%
\fi%
}
% add a `-\overlaynumber` suffix to the next tikzpicture name
% and disable tikz external optimization where needed
\let\orig@tikzsetnextfilename=\tikzsetnextfilename
\renewcommand\tikzsetnextfilename[1]{%
\orig@tikzsetnextfilename{#1-\overlaynumber}%
\tikzifexternalizing{
\if@is@current@pic{\tikzexternal@filenameprefix#1}{%
\tikzset{external/optimize=false}%
}{%
\tikzset{external/optimize=true}%
}%
}{}%
}
\makeatother
\tikzexternalize[only named=true]
\begin{document}
\begin{frame}{pgfplots}
\tikzsetnextfilename{pgfplots}
\begin{tikzpicture}
\begin{axis}
\addplot[visible on=<1-3>] {x};
\addplot[visible on=<2-3>] {exp(x)};
\addplot[visible on=<3-3>] {x*x};
\end{axis}
\end{tikzpicture}
\end{frame}
\begin{frame}{gnuplot}
\tikzsetnextfilename{gnuplot}
\begin{tikzpicture}
\begin{axis}
\addplot[visible on=<1-3>] gnuplot{x};
\addplot[visible on=<2-3>] gnuplot{exp(x)};
\addplot[visible on=<3-3>] gnuplot{x*x};
\end{axis}
\end{tikzpicture}
\end{frame}
\begin{frame}{gnuplot contour}
\tikzsetnextfilename{contour}
\begin{tikzpicture}
\begin{axis}[view={0}{90}, domain=-2:2]
\addplot3[visible on=<1-3>,contour gnuplot={draw color=red,number=20, labels=false}] {x};
\only<2-3>{\addplot3[contour gnuplot={draw color=blue,number=20, labels=false}] {y};}
\only<3>{\addplot3[contour gnuplot={draw color=black,number=20, labels=false}] {x^2+y^2};}
\end{axis}
\end{tikzpicture}
\end{frame}
\end{document}