我正在使用 tikz external 来更快地渲染图表。但如果使用 external,图表中的图例会丢失。
更新:我正在使用创建图例。如果使用,label
则不会发生同样的问题。我想使用\legend
label
。我想使用,因为它为我在 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
同时(使用external
PGFPlots 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}