18

The problem: I have plots with 8 lines, and need to put the legend for all 8 lines into the plot. The document format is IEEE, and the plots need to fit in the single column.

The current solution: I've been able to split the plots by creating two axis, like so:

\begin{tikzpicture}
  \begin{axis}[xlabel=Average Degree, ylabel=Total Weight, legend style={at={(.95,.69)}, label={[font=\footnotesize]left:K/Y+R}, font=\footnotesize, anchor=south east}, legend columns=2, cycle list name={four-1-0}]
    \addplot+[grt] table  [x=links, y=star-red]{\averageone};
    \addplot+[grt] table  [x=links, y=star-red]{\averagetwo};
    \addplot+[grt] table  [x=links, y=star-red]{\averagethree};
    \addplot+[grt] table  [x=links, y=star-red]{\averagefour};
    \addplot+[inv] table [x=links, y=mat-red]{\averageone};
    \addplot+[inv] table [x=links, y=mat-red]{\averagetwo};
    \addplot+[inv] table [x=links, y=mat-red]{\averagethree};
    \addplot+[inv] table [x=links, y=mat-red]{\averagefour};
    \legend{(120),(120),(480),(960)}
  \end{axis}
  \begin{axis}[axis x line=none,axis y line=none, legend style={at={(.95,.68)}, label={[font=\footnotesize]left:DGMM+R}, font=\footnotesize, anchor=north east}, legend columns=2, cycle list name={four-0-1}]
    \addplot+[inv] table  [x=links, y=star-red]{\averageone};
    \addplot+[inv] table  [x=links, y=star-red]{\averagetwo};
    \addplot+[inv] table  [x=links, y=star-red]{\averagethree};
    \addplot+[inv] table  [x=links, y=star-red]{\averagefour};
    \addplot+[bls] table [x=links, y=mat-red]{\averageone};
    \addplot+[bls] table [x=links, y=mat-red]{\averagetwo};
    \addplot+[bls] table [x=links, y=mat-red]{\averagethree};
    \addplot+[bls] table [x=links, y=mat-red]{\averagefour};
    \legend{,,,,(120),(120),(480),(960)}
  \end{axis}
\end{tikzpicture}

The first axis is visible, the second is invisible. The [inv] style creates a line with no line, the [grn] and [bls] tags generate the orange and blue lines, and the cycle lists four-0-1 and four-1-0 set the marks on the invisible lines to none. There are orange lines with circles of the same color as the squares on the blue lines in the bottom two lines, but they are hard to see in this picture. The macros are defined as follows:

\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepackage{pgf}
\usepackage{tikz}
\pgfplotstableread{plts/experiment8b1_av.tab}\averageone
\pgfplotstableread{plts/experiment8b2_av.tab}\averagetwo
\pgfplotstableread{plts/experiment8b3_av.tab}\averagethree
\pgfplotstableread{plts/experiment8b4_av.tab}\averagefour
\pgfplotscreateplotcyclelist{four-1-0}{%
  every mark/.append style={fill=teal}\\%
  every mark/.append style={fill=green}\\%
  every mark/.append style={fill=orange}\\%
  every mark/.append style={fill=pink}\\%
  every mark/.append style={fill=none}\\%
  every mark/.append style={fill=none}\\%
  every mark/.append style={fill=none}\\%
  every mark/.append style={fill=none}\\%
}
\pgfplotscreateplotcyclelist{four-0-1}{%
  every mark/.append style={fill=none}\\%
  every mark/.append style={fill=none}\\%
  every mark/.append style={fill=none}\\%
  every mark/.append style={fill=none}\\%
  every mark/.append style={fill=teal}\\%
  every mark/.append style={fill=green}\\%
  every mark/.append style={fill=orange}\\%
  every mark/.append style={fill=pink}\\%
}
\tikzstyle{bls}=[blue, solid, mark=square*]
\tikzstyle{grt}=[red, solid, mark=*]
\tikzstyle{inv}=[draw=none]

Obviously, this won't compile unless you have the relevant data files, but the output looks like this:

graph

The question: Is there an elegant way to accomplish something very similar to this without building two axis? In some of the other plots I have the two legends have to be in completely different parts of the plot in order to fit them in.

7
  • I'm confused by the part about "the plots need to fit in the single column". What is the obvious choice that isn't acceptable in this case? Dec 1, 2010 at 19:23
  • As opposed to just making the plot big enough to span two columns. IEEEtrans is a two column page.
    – philosodad
    Dec 1, 2010 at 20:06
  • You really should include your "tons of preamble".
    – SamB
    Dec 17, 2010 at 2:16
  • I don't see why. The only lines that aren't are \usepackage statements are style definitions, cyclelist definitions, and data references. None of which have anything to do with the problem, and at least some of which wouldn't do you any good without the data.
    – philosodad
    Dec 20, 2010 at 13:01
  • 4
    @Philosodad. The convention, both here and in other places you can get TeX-related help, is that a minimal example should be something that others can copy-and-paste into their editor of choice. The idea is to minimise both work and misunderstanding by those trying to answer the question. It's always interesting to see what some people feel is 'obvious', for example completely non-standard document classes.
    – Joseph Wright
    Dec 25, 2010 at 9:35

1 Answer 1

19

I'll give it a shot: This solution does not create proper "legends", but merely boxed nodes, so you lose all the nice setup options. It could also probably be solved with a lot more automation (counters, looping and the like).

\documentclass{minimal}

\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}

\begin{axis}
\addplot[label=l1]{0.1*x};
\label{p1}
\addplot{0.2*x};
\label{p2}
\addplot{0.3*x};
\label{p3}
\addplot{0.4*x};
\label{p4}
\addplot{0.5*x};
\label{p5}
\addplot{0.6*x};
\label{p6}

\end{axis}

% Draw first "Legend" node using a left justified shortstack, position using relative axis coordinates
\node [draw,fill=white] at (rel axis cs: 0.8,0.3) {\shortstack[l]{
\ref{p1} $0.1 \cdot x$ \\
\ref{p2} $0.2 \cdot x$ \\
\ref{p3} $0.3 \cdot x$}};

% Second "Legend" node
\node [draw,fill=white] at (rel axis cs: 0.3,0.8) {\shortstack[l]{
\ref{p4} $0.4 \cdot x$ \\
\ref{p5} $0.5 \cdot x$ \\
\ref{p6} $0.6 \cdot x$}};

\end{tikzpicture}
\end{document}

Six plots with two independent pseudo-legends

5
  • I'll give this a shot and see how it works. Thanks!
    – philosodad
    Jan 21, 2011 at 5:23
  • 3
    Very strangely, this strategy does not work with pgfplots externalization. It looks like the label/ref system loses the legend information.
    – pluton
    Oct 19, 2012 at 16:25
  • I find the same thing as @pluton, except occasionally when something else in the picture is broken, which is weird. I've tried compiling numerous times to let the labels resolve, but nothing helps. I'd really like a solution for this.
    – Mike
    Mar 11, 2016 at 19:57
  • 3
    Just came across this rather old post, but I will comment anyways: To get the references right, you need to specify aux in dpth=true when configuring tikzexternalize
    – Dux
    Nov 30, 2016 at 13:07
  • It's working fine for me Sep 20, 2020 at 0:16

You must log in to answer this question.

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