2

I have an error bar chart, where I would like to add a legend. Using this type of code, I am facing problems to add any kind of legend. Please consider my current code:

\newcolumntype{C}[1]{>{\centering\arraybackslash}p{#1}}
\pgfplotsset{
    min max/.style={
        mark=-,
        error bars/.cd,
            y dir=plus,
            y explicit,
            error mark=-,
        /pgfplots/table/.cd,
            x=Time,
            y=Min,
            y error expr=\thisrow{Max}-\thisrow{Min}
    },
    avg avgopen/.style={
        mark=*, mark size=2pt, %mark options={xshift=-2pt},
        error bars/.cd,
            y dir=plus,
            y explicit,
            error mark=square,
        /pgfplots/table/.cd,
            x=Time,
            y=AvgOpen,
            y error expr=\thisrow{Avg}-\thisrow{AvgOpen}
    }
}

\pgfplotstableread{
Time    Avg AvgOpen Min Max
CR  8.63    5.81    4   10
ER  8.17    6.31    3   10
CRER    8.42    5.84    4   10
}\datatableA

\pgfplotstableread{
Time    Avg AvgOpen Min Max
CR  25.02   15.84   6   44
ER  23.17   16.97   6   43
CRER    24.15   15.73   6   45
}\datatableB

\pgfplotstableread{
Time    Avg AvgOpen Min Max
CR  48.24   38.18   13  86
ER  45.47   39.41   12  82
CRER    47.19   38.29   12  85
}\datatableC



\begin{figure}[htbp]
\hspace{-0.5cm}
\begin{tabular}{C{.26\textwidth}C{.26\textwidth}C{.26\textwidth}C{.20\textwidth}}
%%%%%%%%%%%%%%%%%%%%%%
\subfigure [10 loc] {
\begin{tikzpicture}
\begin{axis} [symbolic x coords={CR,ER,CRER},xtick=data,width=0.30\textwidth,height=0.4\textwidth,
                %legend entries={Min, Max, Avg, AvgOpen},
                %legend to name=legend:legend-stats1   
                legend pos=north west,
]
\addplot [min max][forget plot,only marks]  table {\datatableA};
\addplot [avg avgopen][forget plot,only marks] table {\datatableA};
%\legend{$S$};
\end{axis}
\end{tikzpicture}
} & 
%%%%%%%%%%%%%%%%%%%%%%
\subfigure [50 loc] {
\begin{tikzpicture}
\begin{axis} [symbolic x coords={CR,ER,CRER},xtick=data,width=0.30\textwidth,height=0.4\textwidth]
\addplot [min max][forget plot,only marks]  table {\datatableB};
\addplot [avg avgopen][forget plot,only marks] table {\datatableB};
\end{axis}
\end{tikzpicture}
} & 
%%%%%%%%%%%%%%%%%%%%%%
\subfigure [100 loc] {
\begin{tikzpicture}
\begin{axis} [symbolic x coords={CR,ER,CRER},xtick=data,width=0.30\textwidth,height=0.4\textwidth]
\addplot [min max][forget plot,only marks]  table {\datatableC};
\addplot [avg avgopen][forget plot,only marks] table {\datatableC};
\end{axis}
\end{tikzpicture}
} &
%\ref{legend:legend-stats1}
\end{tabular}
\caption{My chart.}
\end{figure}

This gives me a chart such as the following one:

My chart

Now, I would like to add a legend to the right of the 3 subfigures, vertically aligned in the center or at the top, with the following four entries (showing the corresponding symbol):

  • Min

  • Max

  • one entry for the point

  • one entry for the square

Furthermore, I would like to have a little less (horizontal) space between each of the bars.

As mentioned, I was trying to manage this since some time now and I just don't find the right commands. Using legend style, it doesn't have any effect.

Any help is appreciated!

=========================================================

Follow-up:

This helped to build my customized legend:

% argument #1: any options
\newenvironment{customlegend}[1][]{%
    \begingroup
    % inits/clears the lists (which might be populated from previous
    % axes):
    \csname pgfplots@init@cleared@structures\endcsname
    \pgfplotsset{#1}%
}{%
    % draws the legend:
    \csname pgfplots@createlegend\endcsname
    \endgroup
}%

% makes \addlegendimage available (typically only available within an
% axis environment):
\def\addlegendimage{\csname pgfplots@addlegendimage\endcsname}



\begin{figure}[htbp]
\hspace{-0.5cm}
\begin{tabular}{C{.26\textwidth}C{.26\textwidth}C{.26\textwidth}C{.20\textwidth}}
%%%%%%%%%%%%%%%%%%%%%%
\subfigure [10 candidate locations] {
\begin{tikzpicture}
\begin{axis} [symbolic x coords={CR,ER,CRER},xtick=data,width=0.30\textwidth,height=0.4\textwidth,
]
\addplot [min max][forget plot,only marks]  table {\datatableA};
\addplot [avg avgopen][forget plot,only marks] table {\datatableA};
\end{axis}
\end{tikzpicture}
} & 
%%%%%%%%%%%%%%%%%%%%%%
\subfigure [50 candidate locations] {
\begin{tikzpicture}
\begin{axis} [symbolic x coords={CR,ER,CRER},xtick=data,width=0.30\textwidth,height=0.4\textwidth]
\addplot [min max][forget plot,only marks]  table {\datatableB};
\addplot [avg avgopen][forget plot,only marks] table {\datatableB};
\end{axis}
\end{tikzpicture}
} & 
%%%%%%%%%%%%%%%%%%%%%%
\subfigure [100 candidate locations] {
\begin{tikzpicture}
\begin{axis} [symbolic x coords={CR,ER,CRER},xtick=data,width=0.30\textwidth,height=0.4\textwidth]
\addplot [min max][forget plot,only marks]  table {\datatableC};
\addplot [avg avgopen][forget plot,only marks] table {\datatableC};
\end{axis}
\end{tikzpicture}
} &
\begin{tikzpicture}
    \begin{customlegend}[legend entries={Min,Max,Avg,Avg open}]
    \addlegendimage{black,fill=black!50!black,mark=text,text mark={\textipa{\upt}},only marks}
    \addlegendimage{black,fill=black!50!black,,mark=text,text mark={\textipa{\downt}},only marks}
    \addlegendimage{black,fill=black!50!black,mark=square,only marks}
    \addlegendimage{black,fill=black!50!black,mark=*,only marks} % sharp plot
    \end{customlegend}
\end{tikzpicture}
%\ref{legend:legend-stats1}
\end{tabular}
\end{figure}

This gives me a chart as the following one:

The new chart where I still want to align the legend box at the top

Now, I still want to vertically align the legend box at the top. I tried to use vertical alignment of the table cells, without effect. Also, I tried to use:

    legend style={at={(1.0,1.0)},anchor=north}

, which also has no effect.

Does anybody know how I can adjust the vertical alignment of such an customized legend box?

San
  • 113
  • Welcome to TeX.SX! You don't have to sign with your name since it automatically appears in the lower right corner of your post. – jub0bs Sep 06 '13 at 18:12
  • All your plots appear to have the option forget plot which is defined to "allow to include plots which are not remembered for legend entries". This explains why the legend entries have no effect... but it will not solve your problem right away. – Christian Feuersänger Sep 07 '13 at 02:46
  • From what I remember, error bars and their markers do not make it into the legend. Since your plot relies heavily on error bars, you may want to consider writing your own small tikz code to generate a legend. Possibly related: http://tex.stackexchange.com/questions/54794/using-a-pgfplots-style-legend-in-a-plain-old-tikzpicture/54834#54834 – Christian Feuersänger Sep 07 '13 at 02:47
  • Thanks for the answer. I now use a customized legend box as described in the link you provided. However, I still have difficulties to align the legend box at the top. Please see new question above. Many thanks in advance! – San Sep 09 '13 at 21:27
  • Can you try your last column specifier as p{}? – yannisl Sep 09 '13 at 21:52
  • I tried p{} as you suggested: – San Sep 10 '13 at 19:57
  • \begin{tabular}{C{.26\textwidth}C{.26\textwidth}C{.26\textwidth}p{.20\textwidth}}

    Actually with the text-width command inside, because only p{} throws me an error.

    Unfortunately, the legend did not move and still the legend style has no effect.

    – San Sep 10 '13 at 19:58
  • 1
    I did not yet solve my problem, but I found a somehow better way. Using:

    \raisebox{\height}{ ..LEGEND.. }

    I am capable to lift the legend box to be vertically aligned in the center of the chart. Now, I only need to lift it a bit further to be aligned at the top with the chart.

    I am thankful for any hint!

    – San Sep 10 '13 at 20:18

1 Answers1

1

(Presumably an answer to this isn't very interesting for you at this point, but perhaps someone else might be.)

I suggest a different approach. Instead of three subfigures, each with its own tikzpicture environment, use just one tikzpicture with a groupplot instead of axis. The captions are added (in abbreviated form) as titles to each groupplot.

The legend is defined using the normal legend to name feature of pgfplots, and put in a node placed relative to the last groupplot.

As an additional note, the subfigure package that you were using is generally considered deprecated, subcaption should be used instead (or possibly subfig, though that has some issues with hyperref I think).

\documentclass{article}

\usepackage{subcaption} % here used for \phantomsubcaption and subref

\usepackage{pgfplots,pgfplotstable}
\usepgfplotslibrary{groupplots}
\pgfplotsset{compat=1.13}

\pgfplotsset{
    min max/.style={
        mark=-,
        error bars/.cd,
            y dir=plus,
            y explicit,
            error mark=-,
        /pgfplots/table/.cd,
            x=Time,
            y=Min,
            y error expr=\thisrow{Max}-\thisrow{Min}
    },
    avg avgopen/.style={
        mark=*, mark size=2pt, %mark options={xshift=-2pt},
        error bars/.cd,
            y dir=plus,
            y explicit,
            error mark=square,
        /pgfplots/table/.cd,
            x=Time,
            y=AvgOpen,
            y error expr=\thisrow{Avg}-\thisrow{AvgOpen}
    }
}

\pgfplotstableread{
Time    Avg AvgOpen Min Max
CR  8.63    5.81    4   10
ER  8.17    6.31    3   10
CRER    8.42    5.84    4   10
}\datatableA

\pgfplotstableread{
Time    Avg AvgOpen Min Max
CR  25.02   15.84   6   44
ER  23.17   16.97   6   43
CRER    24.15   15.73   6   45
}\datatableB

\pgfplotstableread{
Time    Avg AvgOpen Min Max
CR  48.24   38.18   13  86
ER  45.47   39.41   12  82
CRER    47.19   38.29   12  85
}\datatableC

\begin{document}
\begin{figure}[htbp]
\centering
\begin{tikzpicture}
\begin{groupplot}[
  group style={
    group size=3 by 1,
    group name=plots
  },
  symbolic x coords={CR,ER,CRER},
  xtick=data,
  width=0.3\textwidth,height=0.4\textwidth
]
\nextgroupplot[
  legend entries={Min,Max,Avg,Avg open},
  legend to name=thelegend,
  title={a) 10 CL}]
\addlegendimage{black,fill=black!50!black,mark=text,text mark={x},only marks}
\addlegendimage{black,fill=black!50!black,,mark=text,text mark={o},only marks}
\addplot [only marks,min max]  table {\datatableA};
\addplot [only marks,avg avgopen] table {\datatableA};

\nextgroupplot[title={b) 50 CL}]
\addplot [only marks,min max]  table {\datatableB};
\addplot [only marks,avg avgopen] table {\datatableB};

\nextgroupplot  [title={c) 100 CL}]
\addplot [only marks,min max]  table {\datatableC};
\addplot [only marks,avg avgopen] table {\datatableC};
\end{groupplot}

% add legend
\node [below right,inner sep=0pt] at ([xshift=3mm]plots c3r1.north east) {\ref{thelegend}};

\end{tikzpicture}%
{\phantomsubcaption\label{fig:10cl}}%
{\phantomsubcaption\label{fig:50cl}}%
{\phantomsubcaption\label{fig:100cl}}%
\caption{Something for \subref{fig:10cl}) 10, \subref{fig:50cl}) 50 and \subref{fig:100cl}) 100 candidate locations (CL).}
\end{figure}

\end{document}

enter image description here

Torbjørn T.
  • 206,688