# Pgfplots: Legend with multiple columns and rows, different entry widths

I have two data sets of five curves each that I want to display in one tikzpicture. The five curves of the first data set are solid lines, the five curves of the second data set are dashed. In the legend, I want five entries for the curves (marks only) and two extra to distinguish between the data sets (lines only). Preferably the five curve entries get displayed in one row and the data set entries in a second row. If I do this like my code shows, the the first two columns of BOTH rows are automatically adjusted.

This looks ugly. Is there any way to... ...separately adjust the columns width of each legend row? ...adjust the width of all columns to a fixed width (that matches the width of the longest entry)? ...display the data set entries in a second legend?

I'd also prefer to keep the legend below the plot. Creating in east (outside) of the plot solves the problem but also results in a non-centered plot.

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}

\begin{document}
\begin{tikzpicture}
\begin{axis}
[
ylabel={ylabel},
xlabel={xlabel},
xmin=0,
xmax=120,
ymin=0,
ymax=0.2,
legend columns = 5,
legend style = {at={(0.5, -0.23)}, anchor=north, inner sep=3pt, style={column sep=0.15cm}},       %vorher: at={(1.3, 1)}
legend cell align=left,
ticklabel style={
/pgf/number format/.cd,
fixed,
use comma,
}
]

\addlegendimage{black, only marks, mark=square} % or mark=none?

\addplot[color=black, mark=square, dashed, mark options={solid}] coordinates {(60,0.05)(30,0.18)};
\addplot[color=red, mark=star, dashed, mark options={solid}] coordinates {(60,0.05)(40,0.18)};
\addplot[color=orange, mark=triangle, dashed, mark options={solid}] coordinates {(60,0.05)(50,0.18)};
\addplot[color=green, mark=diamond, dashed, mark options={solid}] coordinates {(60,0.05)(60,0.18)};
\addplot[color=blue, mark=o, dashed, mark options={solid}] coordinates {(60,0.05)(70,0.18)};

\end{axis}
\end{tikzpicture}

\end{document}


• You might find tex.stackexchange.com/questions/54794/… useful for constructing unusual legends. – John Kormylo May 2 at 16:22
• Your code is unfortunately not really compilable. Please consider removing the figure and center environments and replacing \emd{document} by \end{document} and specifying the version e.g. \pgfplotsset{compat=1.16}. – user121799 May 2 at 16:46

This is an ad how way of wasting less space in your specific use case: add an empty column and pretend the long entries have zero width.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\begin{document}
\begin{tikzpicture}
\begin{axis}
[
ylabel={ylabel},
xlabel={xlabel},
xmin=0,
xmax=120,
ymin=0,
ymax=0.2,
legend columns = 5,
legend style = {at={(0.5, -0.23)}, anchor=north, inner sep=3pt, style={column sep=0.15cm}},       %vorher: at={(1.3, 1)}
legend cell align=left,
ticklabel style={
/pgf/number format/.cd,
fixed,
use comma,
}
]

\addlegendimage{black, only marks, mark=square} % or mark=none?

\addplot[color=black, mark=square, dashed, mark options={solid}] coordinates {(60,0.05)(30,0.18)};
\addplot[color=red, mark=star, dashed, mark options={solid}] coordinates {(60,0.05)(40,0.18)};
\addplot[color=orange, mark=triangle, dashed, mark options={solid}] coordinates {(60,0.05)(50,0.18)};
\addplot[color=green, mark=diamond, dashed, mark options={solid}] coordinates {(60,0.05)(60,0.18)};
\addplot[color=blue, mark=o, dashed, mark options={solid}] coordinates {(60,0.05)(70,0.18)};

\end{axis}
\end{tikzpicture}
\end{document}


nodes={text width=width("the longest legend entry")}


to your legend style. It's not entirely automatic as you can see. Instead of width("...") you can of course input a length directly, like text width=3cm.

To make a second legend, you might have to make a new axis, e.g.

\begin{axis}[
hide axis,
legend columns=-1,
legend style={
anchor=north,
at={(0.5,-.4)}
}
]
% dummy plot to make legend show up

\end{axis}


Place that in the same tikzpicture. Here is a complete code demonstrating both of these, but the text width is commented out. I also implemented a custom cycle list which may be of interest, as it save some repetition. But that is a bit besides the point.

A variation of this is to simulate a single legend. Tell pgfplots not to draw the frame of the legends and give each of them a name (name=foo, draw=none in the legend options). Add \usetikzlibrary{fit} to the preamble, and after the second axis add \node [fit=(firstlegendname)(secondlegendname),draw]{};.

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{fit}
\begin{document}
\begin{tikzpicture}
\begin{axis}
[
ylabel={ylabel},
xlabel={xlabel},
xmin=0,
xmax=120,
ymin=0,
ymax=0.2,
legend columns = 5,
legend style = {name=leg1,draw=none,
at={(0.5, -0.23)},
anchor=north,
inner sep=3pt,
style={column sep=0.15cm},
%       nodes={text width=width("the longest legend entry")}
},       %vorher: at={(1.3, 1)}
legend cell align=left,
ticklabel style={
/pgf/number format/.cd,
fixed,
use comma,
},
cycle list={
color=black, mark=square, mark options={solid}\\
color=red, mark=star, mark options={solid}\\
color=orange, mark=triangle, mark options={solid}\\
color=green, mark=diamond, mark options={solid}\\
color=blue, mark=o,  mark options={solid}\\
}
]

\addlegendimage{black, only marks, mark=square} % or mark=none?

\end{axis}

\begin{axis}[
hide axis,
legend columns=-1,
legend style={
name=leg2,draw=none,
anchor=north,
at={(0.5,-.33)}
}
]
% dummy plot to make legend show up