6

So, I need to place my legend outside a groupplot with 2 columns and 2 rows. I'd like to center it either above or below.

I read a lot of similar question on tex@stackexchange, but all of them seems to use labels to reference either the different curves or the entire legend like this, this or this (and many others).

However, I need to externalize my figures since I don't even want to know how much hassle I would go through if I provided tikz figures with references to the journal I'm planning to submit to. Again, tex@stackexchange provides some neat solutions like this or this, but I had quite a struggle to adapt my code neatly to those solutions.

Therefore, I was wondering if there is a quicker way to solve this problem (that of centering my legend on the top outside of a groupplot) WITHOUT the use of labels and references. I know there is a positioning option for the legend, such as legend style={at={(0,0)}}, so I was wondering if it were possible to place some coordinates and do some smart calculations (maybe not even so smart) based on those to position my legend.

Quick MWE; assume that all the plots have the same set of curves which I would reference with the same legend (i left them out in the top 2 plots to avoid including too much code). Can I use the info from c1 and c2 to place the legend exactly on the top-center of my groupplots while calling the command legend in the 3rd plot?

\documentclass{article}

\usepackage[width=18cm]{geometry}
\usepackage{pgfplots}
\usepgfplotslibrary{groupplots}
\usetikzlibrary{pgfplots.groupplots}
\usetikzlibrary{plotmarks}
\usetikzlibrary{calc}
\usepgfplotslibrary{external}

\newcommand{\fwidth}{\textwidth}
\newcommand{\fheight}{3cm}

\begin{document}

\begin{tikzpicture}
%/*
\pgfplotsset{
    scaled y ticks = false,
    width=\fwidth*0.35,
    height=\fheight,
    axis on top,
    xticklabel style={text width=2em,align=center},
    xticklabels={\empty},
    xmin=-5,xmax=5,
    ymin=-5,ymax=5,
    xminorticks=true,
    yminorticks=true,
    ylabel shift={-1.5em},
    ylabel style={align=center}
}
%       
    \begin{groupplot}[ 
        group style={
        group size=2 by 4,
        vertical sep=25pt,
        horizontal sep=35pt
        },
    ]
    % -------------------------------------------------------------------------------------------------------------------
    % Plot [1, 1]
    %-----------
    \nextgroupplot[
            xticklabels={\empty},
            ylabel={ylabel 1},
            title={subtitle 1},
    ]
    % (Relative) Coordinate at top of the first plot
    \coordinate (c1) at (rel axis cs:0,1);
    %-----------
    % Plot [1, 2]
    %-----------
    \nextgroupplot[
            xticklabels={\empty},
            title={subtitle 2},
            ylabel={}
    ]
    % (Relative) Coordinate at top of the second plot
    \coordinate (c2) at (rel axis cs:0,1);
    %-----------
    % Plot [2, 1]
    %-----------
    \nextgroupplot[
            yshift=10pt,
            xlabel={xlabel 1},
            ylabel={ylabel 2},
            legend style={at={($(0,0)+(1cm,1cm)$)},legend columns=4,fill=none,draw=black,anchor=center,align=center},
    ]
    \addplot[color=red,mark=o]{x};
    \addplot[color=blue,dashed]{-x};
    \addplot[color=green]{-0.5*x^3};    
    \addlegendentry{first};    
    \addlegendentry{second};    
    \addlegendentry{third};          
    %-----------    
    % Plot [2, 2]
    %-----------
    \nextgroupplot[
            yshift=10pt,
            xlabel={xlabel 2},
    ]          
    \end{groupplot}
\end{tikzpicture}%

\end{document} 
1
  • Relative to the (current bounding box) or relative to the axis boxes? Jun 18 '16 at 13:32
10

This worked for me, but am not sure if externalize is working. Anyway, I am assuming that \pgfplotslegendfromname does not use the aux file.

\documentclass{article}

\usepackage[width=18cm]{geometry}
\usepackage{pgfplots}
\usepgfplotslibrary{groupplots}
\usetikzlibrary{pgfplots.groupplots}
\usetikzlibrary{plotmarks}
\usetikzlibrary{calc}
\usepgfplotslibrary{external}

\newcommand{\fwidth}{\textwidth}
\newcommand{\fheight}{3cm}

\begin{document}

\begin{tikzpicture}
%/*
\pgfplotsset{
    scaled y ticks = false,
    width=\fwidth*0.35,
    height=\fheight,
    axis on top,
    xticklabel style={text width=2em,align=center},
    xticklabels={\empty},
    xmin=-5,xmax=5,
    ymin=-5,ymax=5,
    xminorticks=true,
    yminorticks=true,
    ylabel shift={-1.5em},
    ylabel style={align=center}
}
%       
    \begin{groupplot}[ 
        group style={
        group size=2 by 4,
        vertical sep=25pt,
        horizontal sep=35pt
        },
    ]
    % -------------------------------------------------------------------------------------------------------------------
    % Plot [1, 1]
    %-----------
    \nextgroupplot[
            xticklabels={\empty},
            ylabel={ylabel 1},
            title={subtitle 1},
    ]
    % (Relative) Coordinate at top of the first plot
    \coordinate (c1) at (rel axis cs:0,1);
    %-----------
    % Plot [1, 2]
    %-----------
    \nextgroupplot[
            xticklabels={\empty},
            title={subtitle 2},
            ylabel={}
    ]
    % (Relative) Coordinate at top of the second plot
    \coordinate (c2) at (rel axis cs:1,1);% I moved this to the upper right corner
    %-----------
    % Plot [2, 1]
    %-----------
    \nextgroupplot[
            yshift=10pt,
            xlabel={xlabel 1},
            ylabel={ylabel 2},
            legend style={at={($(0,0)+(1cm,1cm)$)},legend columns=4,fill=none,draw=black,anchor=center,align=center},
            legend to name=fred
    ]
    \addplot[color=red,mark=o]{x};
    \addplot[color=blue,dashed]{-x};
    \addplot[color=green]{-0.5*x^3};    
    \addlegendentry{first};    
    \addlegendentry{second};    
    \addlegendentry{third};          
    %-----------    
    % Plot [2, 2]
    %-----------
    \nextgroupplot[
            yshift=10pt,
            xlabel={xlabel 2},
    ]          
    \end{groupplot}
    \coordinate (c3) at ($(c1)!.5!(c2)$);
    \node[below] at (c3 |- current bounding box.south)
      {\pgfplotslegendfromname{fred}};
\end{tikzpicture}%

\end{document} 

demo

3
  • Thanks John! It works like a charm! Finally, no problems with the externalization with your solution. FYI, I actually had a small problems in a related problem. If I used the legend coordinates through the positioning command at={(axis description cs:0,0)} instead of at={($(0,0)+(1cm,1cm)$)}, some error would be returned.
    – gbernardi
    Jun 19 '16 at 14:04
  • Outside the axis environment, axis cs is not defined. Create a coordinate where you want the legend to go, then place the (now completed) legend at that coordinate later. Jun 19 '16 at 15:41
  • Makes sense :) Thanks again for your help.
    – gbernardi
    Jun 19 '16 at 15:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.