PGFplots - 组图中的单个图例

PGFplots - 组图中的单个图例

我有一个组图,当我尝试添加图例时,它会在所有子图上重复。我想要整个图的顶部有一个共同的图例线。

\documentclass{standalone}
\usepackage{graphicx}
\usepackage{tikz}
\usepackage{pgfplots}
\usepgfplotslibrary{groupplots}
\pgfplotsset{compat=newest}
\begin{document}

\begin{tikzpicture}
    \begin{groupplot}[group style={group size= 2 by 4},height=5cm,width=6.4cm,legend entries = {curve1,curve2,curve3}]
        \nextgroupplot[title=type1,ylabel={Range1 },symbolic x coords={1,2,4,8,16,32,64,128},xtick=data]
                \addplot[blue]  table{Data/test.dat};
                \addplot[red]   table{Data/test1.dat};
                \addplot[green] table{Data/test2.dat};  
                \coordinate (top) at (rel axis cs:0,1);% coordinate at top of the first plot            
        \nextgroupplot[title=type2,symbolic x coords={1,2,4,8,16,32,64,128},xtick=data]
                \addplot[blue]  table{Data/test.dat};
                \addplot[red]   table{Data/test1.dat};
                \addplot[green] table{Data/test2.dat};
        \nextgroupplot[ylabel={Range2 },symbolic x coords={1,2,4,8,16,32,64,128},xtick=data]
                \addplot[blue]  table{Data/test.dat};
                \addplot[red]   table{Data/test1.dat};
                \addplot[green] table{Data/test2.dat};
        \nextgroupplot[symbolic x coords={1,2,4,8,16,32,64,128},xtick=data]
                \addplot[blue]  table{Data/test.dat};
                \addplot[red]   table{Data/test1.dat};
                \addplot[green] table{Data/test2.dat};
        \nextgroupplot[ylabel={Range3 },symbolic x coords={1,2,4,8,16,32,64,128},xtick=data]
                \addplot[blue]  table{Data/test.dat};
                \addplot[red]   table{Data/test1.dat};
                \addplot[green] table{Data/test2.dat};
        \nextgroupplot[symbolic x coords={1,2,4,8,16,32,64,128},xtick=data]
                \addplot[blue]  table{Data/test.dat};
                \addplot[red]   table{Data/test1.dat};
                \addplot[green] table{Data/test2.dat};
        \nextgroupplot[xlabel={Number of Threads},ylabel={Range4 },symbolic x coords={1,2,4,8,16,32,64,128},xtick=data]
                \addplot[blue]  table{Data/test.dat};
                \addplot[red]   table{Data/test1.dat};
                \addplot[green] table{Data/test2.dat};
        \nextgroupplot[xlabel={Number of Threads},symbolic x coords={1,2,4,8,16,32,64,128},xtick=data]
                \addplot[blue]  table{Data/test.dat};
                \addplot[red]   table{Data/test1.dat};
                \addplot[green] table{Data/test2.dat};
                \coordinate (bot) at (rel axis cs:0,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);
\end{tikzpicture}
\end{document}

输出

答案1

更新

使用group name来引用每个单独的图:

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

\begin{tikzpicture}
    \begin{groupplot}[group style={
                      group name=myplot,
                      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}
        \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};
    \end{groupplot}
    \path (myplot c1r1.outer north west)% plot in column 1 row 1
          -- node[anchor=south,rotate=90] {throughput}% label midway
          (myplot c1r4.outer south west)% plot in column 1 row 4
    ;
% legend
\path (myplot c1r1.north west|-current bounding box.north)--
      coordinate(legendpos)
      (myplot c2r1.north east|-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}

原始答案:

您可以标记图例中应提及的图。然后,您可以参考标记的图例设置图例之外的图例。定义类似于我的回答的坐标你的其它问题. (注意:我改变了节点的定义bot。)

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

\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}

运行两次即可获得

在此处输入图片描述


解释

\path(top|-current bounding box.north)--coordinate(legendpos)(bot|-current bounding box.north);

坐标top设置在第一个图的左上角,而bot设置在最后一个图的右下角。坐标(top|-current bounding box.north)位于一条垂直线top和一条水平线的交点上current bounding box.north。这(bot|-current bounding box.north)仅适用于bot。因此,新坐标labelpos位于当前边界框的北边界上,并且水平居中于图的框。


更新(因为@arunmoehzi 的评论)

您可以使用Ijon Tichy 建议的补丁特克斯世界(德语)将其外部化tikzpicture

\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}只能在第一次运行中使用。

相关内容