Tikz 外部处理优化

Tikz 外部处理优化

由于我的文档中有许多复杂的图表(PGFPlots)以及 Tikz 图像,因此我遇到了 Tikzexternalize 的限制。如果我一次更改两个以上的 tikzpictures,则需要很长时间才能编译文档——至少 15 分钟。

这是因为 tikzexternalize 会读取整个文档并尝试排版每个文本和图形元素。因此,其他 tikzpicture 环境也会被读取和处理,这是不必要的。我想知道,在 tikzpicture 环境中使用 读取之前,是否可以通过一个简单的查询来优化这一点\tikzexternal@nextfile

看看我的第一次尝试(MWE-无法编译)。基本上,verbatim当作业名称不等于 tikzexternal 名称时,我尝试使用环境动态注释掉 tikz 代码。因此,我想在创建特定的外部 tikzpicture 时跳过所有其他 tikzpicture。也许有人知道更好的解决方案或者可以使用和优化我的 mwe。

谢谢您的建议!

您需要在 latex 项目中创建文件夹“tikz”——或者调整前缀。还可以使用--shell-escape选项进行编译

\documentclass[
    titlepage=true,
    fontsize=11pt,
]{article}

\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepgfplotslibrary{external}
\tikzexternalize[mode=convert with system call,optimize=false]
\usepackage{verbatim}
\usepackage{etoolbox} % for ifstrequal


% First adapt tikzexternal@nextfile and define valso mytikznext
\makeatletter
\def\tikzsetnextfilename#1{\gdef\tikzexternal@nextfile{#1}\gdef\mytikznext{#1}}
\makeatother

% New if condition states (ifshowtikztrue / ifshowtikzfalse)
\newif\ifshowtikz

% Adapt tikzpicture enviroment and make use of verbatim
\let\oldtikzpicture\tikzpicture
\let\oldendtikzpicture\endtikzpicture

\renewenvironment{tikzpicture}{%
    \expandafter\ifstrequal\expandafter{\jobname}{\mytikznext}{\showtikztrue}{\showtikzfalse}
    \expandafter\ifstrequal\expandafter{\jobname}{main}{\showtikztrue}{nope}
    
    \ifshowtikz\expandafter\oldtikzpicture%
    \else\expandafter\comment%
    \fi
}{%
    \expandafter\ifstrequal\expandafter{\jobname}{\mytikznext}{\showtikztrue}{\showtikzfalse}
    \expandafter\ifstrequal\expandafter{\jobname}{main}{\showtikztrue}{nope}
    
    \ifshowtikz\expandafter\oldendtikzpicture%
    \else\expandafter\endcomment%
    \fi
}

\begin{document}
\typeout{=== JOB: {\jobname} ===}
\begin{figure}[!t]
    \centering
    \tikzsetnextfilename{test_1}
    \typeout{=== TIKZ: {\mytikznext} ===}
    \tikzset{partial ellipse/.style args =
  {#1:#2:#3}{insert path={+ (#1:#3) arc (#1:#2:#3)}}}
        \begin{tikzpicture}[>=latex]
        %  ellipses
        \draw [fill=white!90!red]    (3,-1.8) ellipse    (4cm and 1 cm);
        \draw [fill=yellow!90!green] (3,-1.8) ellipse (3cm and 0.75 cm);
        \draw [fill=white!90!green]  (3,-1.8) ellipse  (2cm and 0.5 cm);

        % -- Soleil
        \shade [ball color=gray!10!yellow] (3,-1.8) circle (1);
        \node (soleil) at (3,-1.8) {\bf Soleil};
        % partial ellipse pour tracé devant le Soleil
        \draw (3,-1.8) [partial ellipse=220:320:2cm and 0.5cm]
                (3,-1.8) [partial ellipse=220:320:3cm and 0.75cm];

        % Venus
        \shade [ball color=gray!10!orange] (1.6,-1.8) circle (.2);
        \node (venus) at (1.5,-1.45) {Venus}; 

        % ombre de Venus
        \draw[color=white!70!black,fill=white!70!black]
            (1.6,-2.3) ellipse (2mm and 0.5mm);

        % Mercure
        \shade [ball color=gray!10!orange] (5,-1.225) circle (.25);
        \node (mercure) at (5,-0.8) {Mercure}; 

        % Earth
        \shade [ball color=white!50!blue] (5.75,-2.5) circle (.33);
        \node (terre) at (6.6,-2.6) {\bf Terre};

        % Lune
        \shade [ball color=yellow] (5.25,-2.8) circle (.1);
        \node (lune) at (5.25,-3) {Lune};
            
        % Mars
        \draw (3,-1.8) [partial ellipse=45:120:9cm and 2.5cm];
        \shade [ball color=black!50!red] (5,0.66) circle (.15);
        \node (mars) at (5,1) {\bf Mars};   
        % trajet
        \draw [line width=2pt,blue,->,>=latex] (terre) to[out=0,in=0] (mars);   
    \end{tikzpicture}
    \caption[Test1]{Test1.}
    \label{fig:test_1}
\end{figure}

\begin{figure}[!t]
    \centering
    \tikzsetnextfilename{test_2}
    \begin{tikzpicture}[scale=4,cap=round,>=latex]
        % Radius of regular polygons
        \newdimen\R
        \R=0.8cm
        \coordinate (center) at (0,0);
        \draw (0:\R)
            \foreach \x in {60,120,...,360} {  -- (\x:\R) }
                    -- cycle (300:\R) node[below] {$\csc \theta$}
                    -- cycle (240:\R) node[below] {$\sec \theta$}
                    -- cycle (180:\R) node[left] {$\tan \theta$}
                    -- cycle (120:\R) node[above] {$\sin \theta$}
                    -- cycle (60:\R) node[above] {$\cos \theta$}
                    -- cycle (0:\R) node[right] {$\cot \theta$};
        \draw { (60:\R) -- (120:\R) -- (center) -- (60:\R) } [fill=gray];
        \draw { (180:\R) -- (240:\R) -- (center) -- (180:\R) } [fill=gray];
        \draw { (0:\R) -- (300:\R) -- (center) -- (0:\R) }  [fill=gray];
        \R=0.1cm
        \draw (0:\R) \foreach \x in {60,120,...,360} { -- (\x:\R) }
            [fill=white] -- cycle (center) node {1};
    \end{tikzpicture}
    \caption[Test1]{Test2.}
    \label{fig:test_1}
\end{figure}
\end{document}


示例摘自https://texample.net——感谢作者。

编辑:我编译lualatex -shell-escape -synctex=1 -interaction=nonstopmode main.tex

编辑2:您必须编译两次,然后它才能工作.....但不像缩进的那样:在单独的调用中编译 tikzpicture 时它仍然会说:

=== JOB: {main} ===
=== TIKZ: {test_1} ===

因此 if 语句不起作用......

编辑3:添加了以下选项external/system call

\makeatletter
    \tikzset{%
        external/prefix=tikz/,
        external/system call={%
            lualatex %
                \tikzexternalcheckshellescape %
                -shell-escape %
                -interaction=nonstopmode%
                -interaction=batchmode %
                %-output-directory="tikz" %
                -jobname "\mytikznext" %
                "\texsource"%
        },
        %/pgf/images/include external/.code={%
        %    \includegraphics{tikz/#1}%
        %},%
    }
\makeatother

但输出仍然不正确,分别是字符串的比较不能按预期进行:

=== JOB: {test1} ===
=== TIKZ: {test1} ===
=== NOTSAME === <---------- WHY?
=== JOB: {test1} ===
=== TIKZ: {test2} ===
=== NOTSAME ===

新的完整“MWE”:

\documentclass[
    fontsize=11pt,
]{article}

\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepgfplotslibrary{external}
\tikzexternalize%[prefix=tikz/,mode=convert with system call,optimize=false]
\usepackage{verbatim}
\usepackage{etoolbox} % for ifstrequal


% First adapt tikzexternal@nextfile and define valso mytikznext
\makeatletter
\def\tikzsetnextfilename#1{\gdef\tikzexternal@nextfile{#1}\gdef\mytikznext{#1}}
\makeatother

\makeatletter
    \tikzset{%
        external/prefix=tikz/,
        external/system call={%
            lualatex %
                \tikzexternalcheckshellescape %
                -shell-escape %
                -interaction=nonstopmode%
                -interaction=batchmode %
                %-output-directory="tikz" %
                -jobname "\mytikznext" %
                "\texsource"%
        },
        %/pgf/images/include external/.code={%
        %    \includegraphics{tikz/#1}%
        %},%
    }
\makeatother

% New if condition states (ifshowtikztrue / ifshowtikzfalse)
\newif\ifshowtikz

% Adapt tikzpicture enviroment and make use of verbatim
\let\oldtikzpicture\tikzpicture
\let\oldendtikzpicture\endtikzpicture

\renewenvironment{tikzpicture}{%
    \typeout{=== JOB: {\jobname} ===}
    \typeout{=== TIKZ: {\mytikznext} ===}
    \expandafter\ifstrequal\expandafter{\jobname}{\mytikznext}{\typeout{=== SAME ===}}{\typeout{=== NOTSAME ===}}

    \expandafter\ifstrequal\expandafter{\jobname}{\mytikznext}{\showtikztrue}{\showtikzfalse}
    \expandafter\ifstrequal\expandafter{\jobname}{main}{\showtikztrue}{nope}
    
    \ifshowtikz\expandafter\oldtikzpicture%
    \else\expandafter\comment%
    \fi
}{%
    
    \ifshowtikz\expandafter\oldendtikzpicture%
    \else\expandafter\endcomment%
    \fi
}

\begin{document}
\begin{figure}[!t]
    \centering
    \tikzsetnextfilename{test1}
    \tikzset{partial ellipse/.style args =
  {#1:#2:#3}{insert path={+ (#1:#3) arc (#1:#2:#3)}}}
        \begin{tikzpicture}[>=latex]
        %  ellipses
        \draw [fill=white!90!red]    (3,-1.8) ellipse    (4cm and 1 cm);
        \draw [fill=yellow!90!green] (3,-1.8) ellipse (3cm and 0.75 cm);
        \draw [fill=white!90!green]  (3,-1.8) ellipse  (2cm and 0.5 cm);

        % -- Soleil
        \shade [ball color=gray!10!yellow] (3,-1.8) circle (1);
        \node (soleil) at (3,-1.8) {\bf Soleil};
        % partial ellipse pour tracé devant le Soleil
        \draw (3,-1.8) [partial ellipse=220:320:2cm and 0.5cm]
                (3,-1.8) [partial ellipse=220:320:3cm and 0.75cm];

        % Venus
        \shade [ball color=gray!10!orange] (1.6,-1.8) circle (.2);
        \node (venus) at (1.5,-1.45) {Venus}; 

        % ombre de Venus
        \draw[color=white!70!black,fill=white!70!black]
            (1.6,-2.3) ellipse (2mm and 0.5mm);

        % Mercure
        \shade [ball color=gray!10!orange] (5,-1.225) circle (.25);
        \node (mercure) at (5,-0.8) {Mercure}; 

        % Earth
        \shade [ball color=white!50!blue] (5.75,-2.5) circle (.33);
        \node (terre) at (6.6,-2.6) {\bf Terre};

        % Lune
        \shade [ball color=yellow] (5.25,-2.8) circle (.1);
        \node (lune) at (5.25,-3) {Lune};
            
        % Mars
        \draw (3,-1.8) [partial ellipse=45:120:9cm and 2.5cm];
        \shade [ball color=black!50!red] (5,0.66) circle (.15);
        \node (mars) at (5,1) {\bf Mars};   
        % trajet
        \draw [line width=2pt,blue,->,>=latex] (terre) to[out=0,in=0] (mars);   
    \end{tikzpicture}
    \caption[Test1]{Test1.}
    \label{fig:test_1}
\end{figure}

\begin{figure}[!t]
    \centering
    \tikzsetnextfilename{test2}
    \begin{tikzpicture}[scale=4,cap=round,>=latex]
        % Radius of regular polygons
        \newdimen\R
        \R=0.8cm
        \coordinate (center) at (0,0);
        \draw (0:\R)
            \foreach \x in {60,120,...,360} {  -- (\x:\R) }
                    -- cycle (300:\R) node[below] {$\csc \theta$}
                    -- cycle (240:\R) node[below] {$\sec \theta$}
                    -- cycle (180:\R) node[left] {$\tan \theta$}
                    -- cycle (120:\R) node[above] {$\sin \theta$}
                    -- cycle (60:\R) node[above] {$\cos \theta$}
                    -- cycle (0:\R) node[right] {$\cot \theta$};
        \draw { (60:\R) -- (120:\R) -- (center) -- (60:\R) } [fill=gray];
        \draw { (180:\R) -- (240:\R) -- (center) -- (180:\R) } [fill=gray];
        \draw { (0:\R) -- (300:\R) -- (center) -- (0:\R) }  [fill=gray];
        \R=0.1cm
        \draw (0:\R) \foreach \x in {60,120,...,360} { -- (\x:\R) }
            [fill=white] -- cycle (center) node {1};
    \end{tikzpicture}
    \caption[Test1]{Test2.}
    \label{fig:test_2}
\end{figure}
\end{document}

相关内容