1

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.

Thanks in advance.

\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?
    \addlegendentry{Entry1}

    \addlegendimage{red, only marks, mark=asterisk}
    \addlegendentry{Entry2}

    \addlegendimage{orange, only marks, mark=triangle}
    \addlegendentry{Entry3}

    \addlegendimage{green, only marks, mark=diamond}
    \addlegendentry{Entry4}

    \addlegendimage{blue, only marks, mark=o}
    \addlegendentry{Entry5}

    \addlegendimage{black, line legend}
    \addlegendentry{AlternativeEntry1}

    \addlegendimage{black, line legend, dashed}
    \addlegendentry{AlternativeEntry2}

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

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

Two data sets with five curves each

  • 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
1

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?
    \addlegendentry{Entry1}

    \addlegendimage{red, only marks, mark=asterisk}
    \addlegendentry{Entry2}

    \addlegendimage{orange, only marks, mark=triangle}
    \addlegendentry{Entry3}

    \addlegendimage{green, only marks, mark=diamond}
    \addlegendentry{Entry4}

    \addlegendimage{blue, only marks, mark=o}
    \addlegendentry{Entry5}

    \addlegendimage{black, line legend}
    \addlegendentry{\makebox[0pt][l]{AlternativeEntry1}}

    \addlegendimage{empty legend}
    \addlegendentry{}
    \addlegendimage{black, line legend, dashed}
    \addlegendentry{\makebox[0pt][l]{AlternativeEntry2}}

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

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

enter image description here

1

For your second option, adjusting the cell widths, you just need to add

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
\addplot[forget plot] coordinates {(0,0)};

\addlegendimage{black, line legend}
\addlegendentry{AlternativeEntry1}

\addlegendimage{black, line legend, dashed}
\addlegendentry{AlternativeEntry2}

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

enter image description here

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?
    \addlegendentry{Entry1}

    \addlegendimage{red, only marks, mark=asterisk}
    \addlegendentry{Entry2}

    \addlegendimage{orange, only marks, mark=triangle}
    \addlegendentry{Entry3}

    \addlegendimage{green, only marks, mark=diamond}
    \addlegendentry{Entry4}

    \addlegendimage{blue, only marks, mark=o}
    \addlegendentry{Entry5}

    \addplot coordinates {(20,0.05)(30,0.15)};
    \addplot coordinates {(20,0.05)(40,0.15)};
    \addplot coordinates {(20,0.05)(50,0.15)};
    \addplot coordinates {(20,0.05)(60,0.15)};
    \addplot coordinates {(20,0.05)(70,0.15)};


    \addplot+[dashed] coordinates {(60,0.05)(30,0.18)};
    \addplot+[dashed] coordinates {(60,0.05)(40,0.18)};
    \addplot+[dashed] coordinates {(60,0.05)(50,0.18)};
    \addplot+[dashed] coordinates {(60,0.05)(60,0.18)};
    \addplot+[dashed] coordinates {(60,0.05)(70,0.18)};

    \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
    \addplot[forget plot] coordinates {(0,0)};

    \addlegendimage{black, line legend}
    \addlegendentry{AlternativeEntry1}

    \addlegendimage{black, line legend, dashed}
    \addlegendentry{AlternativeEntry2}

    \end{axis}

    \node [fit=(leg1)(leg2),draw] {};
    \end{tikzpicture}
\end{document}

enter image description here

  • Thanks for your solutions, too! – blowcake May 2 at 16:58

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.