5

Based on a question and the answer I have provided for it; now I have a question about adding legend to a plot which is made by means of the layered feature of the pgfplots.

As far as the legend option is defined in the axis environment; and the layer feature allows to combine multiple separate axis environments like this:

enter image description here

but I can not find a way to add a legend for the whole plot like this:

enter image description here

How can I add a complete legend for the whole pgfplots layer plot.

enter image description here

\documentclass[margin=1mm]{standalone}
\usepackage{filecontents}
\usepackage{pgfplots}
\usepgfplotslibrary{statistics}

\begin{document}

    \begin{tikzpicture}[
    declare function={gamma(\z)= 2.506628274631*sqrt(1/\z)+ 0.20888568*(1/\z)^(1.5)+ 0.00870357*(1/\z)^(2.5)- (174.2106599*(1/\z)^(3.5))/25920- (715.6423511*(1/\z)^(4.5))/1244160)*exp((-ln(1/\z)-1)*\z;},
    declare function={gammapdf(\x,\k,\theta) = 1/(\theta^\k)*1/(gamma(\k))*\x^(\k-1)*exp(-\x/\theta);},
    declare function={cauchypdf(\x,\mu,\gamma) = 1/(pi*\gamma*(1+((\x-\mu)/\gamma)^2));}
    ]
    \pgfplotsset{set layers}
    \begin{axis}[
    axis y line*=left,
    ylabel=Histogram,
    every axis y label/.style={rotate=90, blue, at={(-0.15,0.5)},},
    ybar,
    ymin=0,
    yticklabel style={blue},
    ]

    \addplot +[hist] table [y index=0, col sep=comma,row sep=newline] {
        data
        48
        51
        48
        51
        66
        0
        0
        25
        31
        60
        9
        43
        49
        15
        22
        1
    };
    \end{axis}

    \begin{axis}[
    ylabel style={black}, 
    axis y line*=right,
    axis x line=none,
    ylabel=PDF's,
    every axis y label/.style={rotate=-90, black, at={(1.15,0.5)},},
    /pgfplots/every y tick scale label/.style={
        at={(1,1)},
        above right,
        inner sep=0pt,
        yshift=0.3em,
    },
    yticklabel style={black},
    legend entries={
        $\textbf{Gamma}~\alpha=1.7435~ \beta=21.263$,
        $~\textbf{Cauchy}~\sigma=16.1340~ \mu=39.554$
    },
    legend style={at={(0.5,-0.15)},anchor=north},
    ymin=0,
    ]

    \addplot [thick, smooth, domain=0:66, black, mark=square] {gammapdf(x,1.7435, 21.263)};
    \addplot [thick, smooth, domain=0:66, red, mark=triangle] {cauchypdf(x,39.554, 16.134)};
    \end{axis}
    \end{tikzpicture}
\end{document}

1 Answer 1

6

You can label each plot and then set the legend as a tikz matrix outside the axis environments.

\documentclass[margin=1mm]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{statistics}

\usetikzlibrary{matrix}

\begin{document}

    \begin{tikzpicture}[
    declare function={gamma(\z)= 2.506628274631*sqrt(1/\z)+ 0.20888568*(1/\z)^(1.5)+ 0.00870357*(1/\z)^(2.5)- (174.2106599*(1/\z)^(3.5))/25920- (715.6423511*(1/\z)^(4.5))/1244160)*exp((-ln(1/\z)-1)*\z;},
    declare function={gammapdf(\x,\k,\theta) = 1/(\theta^\k)*1/(gamma(\k))*\x^(\k-1)*exp(-\x/\theta);},
    declare function={cauchypdf(\x,\mu,\gamma) = 1/(pi*\gamma*(1+((\x-\mu)/\gamma)^2));}
    ]
    \pgfplotsset{set layers}
    \begin{axis}[
    axis y line*=left,
    ylabel=Histogram,
    every axis y label/.style={rotate=90, blue, at={(-0.15,0.5)},},
    ybar,
    ymin=0,
    yticklabel style={blue},
    ]

    \addplot +[hist] table [y index=0, col sep=comma,row sep=newline] {
        data
        48
        51
        48
        51
        66
        0
        0
        25
        31
        60
        9
        43
        49
        15
        22
        1
    };\label{plots:hist}
    \end{axis}

    \begin{axis}[
    ylabel style={black}, 
    axis y line*=right,
    axis x line=none,
    ylabel=PDF's,
    every axis y label/.style={rotate=-90, black, at={(1.15,0.5)},},
    /pgfplots/every y tick scale label/.style={
        at={(1,1)},
        above right,
        inner sep=0pt,
        yshift=0.3em,
    },
    yticklabel style={black},
    ymin=0,
    ]

    \addplot [thick, smooth, domain=0:66, black, mark=square] {gammapdf(x,1.7435, 21.263)};
        \label{plots:gamma}
    \addplot [thick, smooth, domain=0:66, red, mark=triangle] {cauchypdf(x,39.554, 16.134)};
        \label{plots:cauchy}
    \end{axis}
% Legend
    \matrix[
        matrix of nodes,
        draw,
        anchor=north,
        column 1/.style={nodes={anchor=center}},
        column 2/.style={nodes={anchor=west}}
      ] at([yshift=-2.5em]current axis.south)
      {
        \ref{plots:gamma}&$\textbf{Gamma}~\alpha=1.7435~ \beta=21.263$\\
        \ref{plots:cauchy}&$\textbf{Cauchy}~\sigma=16.1340~ \mu=39.554$\\
        \ref{plots:hist}&Histogram\\};
    \end{tikzpicture}
\end{document}

enter image description here


Because of a comment by Iony:

You can use a patch suggested by Ijon Tichy on www.texwelt.de to externalize this tikzpicture:

%%% %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
%%%

and then \nextwithlateexternal immediately before this tikzpicture environment. Run twice with -shell-escape.

First run:

enter image description here

Second run:

enter image description here

Code:

\documentclass[margin=1mm]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{statistics}
\usetikzlibrary{matrix}

\usepgfplotslibrary{external}
\tikzexternalize
\tikzsetexternalprefix{external_figs/}

%%% %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}[
    declare function={gamma(\z)= 2.506628274631*sqrt(1/\z)+ 0.20888568*(1/\z)^(1.5)+ 0.00870357*(1/\z)^(2.5)- (174.2106599*(1/\z)^(3.5))/25920- (715.6423511*(1/\z)^(4.5))/1244160)*exp((-ln(1/\z)-1)*\z;},
    declare function={gammapdf(\x,\k,\theta) = 1/(\theta^\k)*1/(gamma(\k))*\x^(\k-1)*exp(-\x/\theta);},
    declare function={cauchypdf(\x,\mu,\gamma) = 1/(pi*\gamma*(1+((\x-\mu)/\gamma)^2));}
    ]
    \pgfplotsset{set layers}
    \begin{axis}[
    axis y line*=left,
    ylabel=Histogram,
    every axis y label/.style={rotate=90, blue, at={(-0.15,0.5)},},
    ybar,
    ymin=0,
    yticklabel style={blue},
    ]

    \addplot +[hist] table [y index=0, col sep=comma,row sep=newline] {
        data
        48
        51
        48
        51
        66
        0
        0
        25
        31
        60
        9
        43
        49
        15
        22
        1
    };\label{plots:hist}
    \end{axis}

    \begin{axis}[
    ylabel style={black}, 
    axis y line*=right,
    axis x line=none,
    ylabel=PDF's,
    every axis y label/.style={rotate=-90, black, at={(1.15,0.5)},},
    /pgfplots/every y tick scale label/.style={
        at={(1,1)},
        above right,
        inner sep=0pt,
        yshift=0.3em,
    },
    yticklabel style={black},
    ymin=0,
    ]

    \addplot [thick, smooth, domain=0:66, black, mark=square] {gammapdf(x,1.7435, 21.263)};
        \label{plots:gamma}
    \addplot [thick, smooth, domain=0:66, red, mark=triangle] {cauchypdf(x,39.554, 16.134)};
        \label{plots:cauchy}
    \end{axis}
% Legend
    \matrix[
        matrix of nodes,
        draw,
        anchor=north,
        column 1/.style={nodes={anchor=center}},
        column 2/.style={nodes={anchor=west}}
      ] at([yshift=-2.5em]current axis.south)
      {
        \ref{plots:gamma}&$\textbf{Gamma}~\alpha=1.7435~ \beta=21.263$\\
        \ref{plots:cauchy}&$\textbf{Cauchy}~\sigma=16.1340~ \mu=39.554$\\
        \ref{plots:hist}&Histogram\\};
    \end{tikzpicture}
\end{document}
4
  • There is a problem if you use Tikz/external tex.stackexchange.com/questions/36786/…
    – lony
    Nov 18, 2014 at 12:28
  • 1
    @Iony see my additions to the post.
    – esdd
    Nov 19, 2014 at 11:36
  • Wow, thats a lot of hacking done for just some labels. Thanks to KA. German comments make me curious :)
    – lony
    Nov 19, 2014 at 15:21
  • Sadly the patch isn't working running your compilation with latexmk
    – lony
    Nov 20, 2014 at 11:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .