pgfplots-tikz 外部-缺少图例

pgfplots-tikz 外部-缺少图例

我正在使用 tikz external 来更快地渲染图表。但如果使用 external,图表中的图例会丢失。

更新:我正在使用创建图例。如果使用,label则不会发生同样的问题。我想使用\legendlabel。我想使用,因为它为我在 groupplot 中提供了更大的灵活性。查看问题PGFplots - 群组图中的单个图例

主文件

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\usetikzlibrary{pgfplots.groupplots,external}
\tikzexternalize[prefix=tikz/]
\tikzset{external/force remake}
\begin{document}
\begin{figure}
    \input{sample.tikz}         % input TiKZ figure code
    \caption{legends missing in tikz external}  % caption
    \label{fig:sample}              % label
\end{figure}
\end{document}

样本.tikz

% Style to select only points from #1 to #2 (inclusive)
\pgfplotsset
{
    select coords between index/.style 2 args=
    {
        x filter/.code=
        {
                \ifnum\coordindex<#1\def\pgfmathresult{}\fi
                \ifnum\coordindex>#2\def\pgfmathresult{}\fi
        }
    }
}
\begin{tikzpicture}
    \begin{groupplot}[group style={group size= 2 by 1},height=4cm,width=4cm,max space between ticks=20,minor tick num=1,tick label style={font=\footnotesize}]
        \nextgroupplot[title={2K},xtick=data]
                \addplot[blue,dotted,mark=asterisk]         [select coords between index={0}{4}] table[x=threads,y=foo-MOPS,col sep=space]{Data/mic/threadSweep.csv};       \label{plots:foo:cka}
                \addplot[green, dotted,mark=o]              [select coords between index={0}{4}] table[x=threads,y=bar-MOPS,col sep=space]{Data/mic/threadSweep.csv};       \label{plots:bar:cka}
                \coordinate (top) at (rel axis cs:0,1);% coordinate at top of the first plot
        \nextgroupplot[title={20K} ,xtick=data] 
                \addplot[blue,dotted,mark=asterisk]         [select coords between index={5}{9}] table[x=threads,y=foo-MOPS,col sep=space]{Data/mic/threadSweep.csv};  
                \addplot[green, dotted,mark=o]              [select coords between index={5}{9}] table[x=threads,y=bar-MOPS,col sep=space]{Data/mic/threadSweep.csv}; 
                \coordinate (bot) at (rel axis cs:1,0);% coordinate at bottom of the last plot
\end{groupplot}
    \path (top-|current bounding box.west)-- node[anchor=south,rotate=90] {\small system throughput} (bot-|current bounding box.west);
    \path (top|-current bounding box.north)-- coordinate(legendpos) (bot|-current bounding box.north);
    \matrix[matrix of nodes, anchor=south, draw, inner sep=0.2em, draw] at ([yshift=1ex]legendpos)
    {
        \ref{plots:foo:cka}&    foo         & [5pt]
        \ref{plots:bar:cka}&    bar         \\
    };
\end{tikzpicture}

输出 在此处输入图片描述

答案1

您可以使用Ijon Tichy 建议的补丁特克斯世界(德语)将tikzpicture使用\label\ref传说外化。

以下示例来自PGFplots - 群组图中的单个图例因为我没有threadSweep.csv

\documentclass[margin=5mm]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{matrix}
\usepgfplotslibrary{groupplots}
\pgfplotsset{compat=newest}

\usepgfplotslibrary{external}
\tikzexternalize
\tikzsetexternalprefix{external_figs/}
\tikzset{external/up to date check=md5}% < added

%%% %http://texwelt.de/wissen/fragen/9476/labels-an-pgfplots/9527 (by Ijon Tichy)
\usepackage{scrlfile}
\usepackage{etoolbox}
\makeatletter
\newif\if@lateexternal
\newcommand*{\nextwithlateexternal}{\@lateexternaltrue}
\renewcommand*{\@lateexternalfalse}{\global\let\if@lateexternal\iffalse}
% Den Systemaufruf von external so ändern, dass er optional doppelt
% stattfindet: Zunächst wie gehabt unmittelbar und zusätzlich nachdem
% die aux-Datei geschlossen (und sogar neu gelesen) wurde.
\patchcmd\tikzexternal@externalizefig@systemcall@@
  {\immediate\write18{\pgf@tempa}}%
  {\immediate\write18{\pgf@tempa}%
    \if@lateexternal
      \begingroup
        \protected@edef\reserved@a{%
          \noexpand\endgroup
          \noexpand\AfterReadingMainAux{%
            \noexpand\immediate\noexpand\write18{%
              \expandafter\detokenize\expandafter{\pgf@tempa}}%
          }%
        }%
      \reserved@a
    \fi
  }%
  {}%
  {\patchFailedError}
% Nun dafür sorgen, dass der Aufruf \nextwithlateexternal nur auf
% den nächsten potentiellen Systemaufruf von external wirkt statt
% auf den nächsten tatsächlichen oder gar alle:
\apptocmd\tikzexternal@externalizefig@systemcall@@
  {\@lateexternalfalse}
  {}
  {\patchFailedError}
\makeatother
%%%


\begin{document}

\nextwithlateexternal% < added
\begin{tikzpicture}
    \begin{groupplot}[group style={group size= 2 by 4},height=5cm,width=6.4cm]
        \nextgroupplot[title=type1,ylabel={Range1 }]
                \addplot[blue] {x};\label{plots:plot1}
                \addplot[red] {x^2};\label{plots:plot2}
                \addplot[green] {2*x};\label{plots:plot3}
                \coordinate (top) at (rel axis cs:0,1);% coordinate at top of the first plot
        \nextgroupplot[title=type2]
                \addplot[blue]{x};
        \nextgroupplot[ylabel={Range2 }]
                \addplot[blue]{x};
        \nextgroupplot
                \addplot[blue]{x};
        \nextgroupplot[ylabel={Range3 }]
                \addplot[blue]{x};
        \nextgroupplot
                \addplot[blue]{x};
        \nextgroupplot[xlabel={Number of Threads},ylabel={Range4 }]
                \addplot[blue]{x};
        \nextgroupplot[xlabel={Number of Threads}]
                \addplot[blue]{x};
                \coordinate (bot) at (rel axis cs:1,0);% coordinate at bottom of the last plot
    \end{groupplot}
    \path (top-|current bounding box.west)-- 
          node[anchor=south,rotate=90] {throughput} 
          (bot-|current bounding box.west);
% legend
\path (top|-current bounding box.north)--
      coordinate(legendpos)
      (bot|-current bounding box.north);
\matrix[
    matrix of nodes,
    anchor=south,
    draw,
    inner sep=0.2em,
    draw
  ]at([yshift=1ex]legendpos)
  {
    \ref{plots:plot1}& curve 1&[5pt]
    \ref{plots:plot2}& curve2&[5pt]
    \ref{plots:plot3}& curve 3\\};
\end{tikzpicture}
\end{document}

運行兩次。

注意:据我所知,这不适用于latexmk。并且\tikzset{external/force remake}只能在第一次运行中使用。

答案2

您需要阅读使用说明\label\ref需要pgf图手册中有关外部化的部分。(我的副本中为第 7.1 节。)

如果您希望将这些与外部化相结合,则不能使用默认模式。您需要使用其中一种可用替代方案。

摘自pgf图手动的:

对于点 a),\ref外部化图形的内部仅当您手动或通过 make 发出所需的系统调用时才有效。初始配置mode=convert with system call不支持\ref。但您可以复制粘贴生成的系统调用mode=convert with system call并手动发出。原因是\ref 信息存储在主.aux文件中 - 但调用时此辅助文件未完全写入mode=convert with system call(存在竞争条件)。请注意\pageref不支持(抱歉)。因此:如果您有\ref外部图形的内部,请考虑使用mode=list and make或复制粘贴图像的系统调用并手动发出。

答案3

同时(使用externalPGFPlots v1.14 库),只需编译以下 MWE 两次即可获得所需的结果...

(我刚刚删除了 MWE 中间两行图以节省一些空间。)

\documentclass{article}
\usepackage{pgfplots}
    \usetikzlibrary{
        matrix,
        pgfplots.external,
        pgfplots.groupplots,
    }
    \pgfplotsset{compat=1.3}
    \tikzexternalize
\begin{document}
    \begin{tikzpicture}
        \begin{groupplot}[
            group style={
                group size= 2 by 2,
            },
            height=5cm,
            width=6.4cm,
        ]
        \nextgroupplot[title=type1,ylabel={Range1 }]
            \addplot[blue] {x};\label{plots:plot1}
            \addplot[red] {x^2};\label{plots:plot2}
            \addplot[green] {2*x};\label{plots:plot3}
            \coordinate (top) at (rel axis cs:0,1);% coordinate at top of the first plot
        \nextgroupplot[title=type2]
            \addplot[blue]{x};
        \nextgroupplot[xlabel={Number of Threads},ylabel={Range4 }]
            \addplot[blue]{x};
        \nextgroupplot[xlabel={Number of Threads}]
            \addplot[blue]{x};
            \coordinate (bot) at (rel axis cs:1,0);% coordinate at bottom of the last plot
        \end{groupplot}
        \path (top-|current bounding box.west)--
              node[anchor=south,rotate=90] {throughput}
              (bot-|current bounding box.west);
        % legend
        \path (top|-current bounding box.north)--
              coordinate(legendpos)
              (bot|-current bounding box.north);
        \matrix[
            matrix of nodes,
            anchor=south,
            draw,
            inner sep=0.2em,
        ] at ([yshift=1ex]legendpos) {
            \ref{plots:plot1}& curve 1&[5pt]
            \ref{plots:plot2}& curve2&[5pt]
            \ref{plots:plot3}& curve 3\\
        };
    \end{tikzpicture}
\end{document}

该图显示了上述代码不带空格的结果

相关内容