Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I'd like to plot a few sets of data using the groupplots library of pgfplots. On each plot, I'd like to add a few other pieces of data that do not change from plot to plot. So I put the plot commands in a \foreach loop, but I can't get the legend entries to come from the input table describing these extra data. I tried something similar to the top answer in Use first row of a table as legend entry in pgfplot graph?, but it would not compile (when resolving references the second time around it did not like \colname).

Below is an example and the output. The correct answer will rename the labels from 'Model' to the columns from \modeltable. (It would also be nice to space the labels a bit further out in the horizontal direction...)

\documentclass[crop]{standalone}

\usepackage[svgnames]{xcolor}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{groupplots}

\pgfplotsset{% global config
  compat=newest,
  every minor tick={very thin, gray},
  minor tick num=4,
  enlargelimits=0.02,
  group style={
    columns=2,
    xlabels at=edge bottom,
    ylabels at=edge left},
  every axis legend/.append style={
    legend cell align=left,
    legend columns=4
  }
}

\pgfplotstableread{
  Time      {Model A}   {Model G}   {Model Z}
  0         1           1           1
  1         1           2           2
  2         2           3           3
  3         3           4           4
  4         5           5           8
  5         8           6           10
  6         13          7           16
}\modeltable

\pgfplotstableread{
  Time      {Data 1}  {Data 2}
  0         1.3       2.3
  1         2.6       3.6
  2         3.8       4.8
  3         7.9       5.9
  4         6.3       7.3
  5         7.5       6.5
  6         9.0       8.9
}\datatable

\begin{document}

  \begin{tikzpicture}

    \begin{groupplot}[
      xlabel={Time},
      ylabel={Amplitude},
      every axis title shift=0,
      legend to name=grouplegend]

      \pgfplotsinvokeforeach{1,2}{%
        \nextgroupplot[title=Data $#1$]

        % Models
        \foreach \y in {1, 2, 3} {
          \addplot [smooth, dashed, color=DarkRed]
            table[x index=0, y index=\y] {\modeltable};
          %\pgfplotstablegetcolumnnamebyindex{\y}\of{\modeltable}\to{\colname}
          %\addlegendentry {\colname}
          \addlegendentry{Model}
        }

        % Data
        \addplot [only marks, mark=o]
          table[x index=0, y index=#1] {\datatable};
        \addlegendentry {Data}
      }

    \end{groupplot}

    \node (dummytitle) at ($(group c1r1.north)!0.5!(group c2r1.north)$)
      [above]{};
    \node (title) at (dummytitle.north)
      [above, yshift=\pgfkeysvalueof{/pgfplots/every axis title shift}]
      {Experimental Data};

    \node (legend) at ($(group c1r1.south)!0.5!(group c2r1.south)$)
      [below, yshift=-2\pgfkeysvalueof{/pgfplots/every axis title shift}]
      {\ref{grouplegend}};

  \end{tikzpicture}

\end{document}

Two-column plot with uninformative legend

share|improve this question

1 Answer 1

up vote 7 down vote accepted

By default, the entries you add using \addlegendentry are not expanded, so they all consist of just \colname at the time when the legend is called, which is outside the scope where \colname is defined. This can be fixed by using \addlegendentryexpanded{...} instead.

I've also taken the liberty to add a little more space between the legend entries (as described in How can I adjust the horizontal spacing between legend entries in PGFPlots?):

\documentclass[]{standalone}

\usepackage[svgnames]{xcolor}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{groupplots}

\pgfplotsset{% global config
  compat=newest,
  every minor tick={very thin, gray},
  minor tick num=4,
  enlargelimits=0.02,
  group style={
    columns=2,
    xlabels at=edge bottom,
    ylabels at=edge left},
  every axis legend/.append style={
    legend cell align=left,
    legend columns=4
  }
}

\pgfplotstableread{
  Time      {Model A}   {Model G}   {Model Z}
  0         1           1           1
  1         1           2           2
  2         2           3           3
  3         3           4           4
  4         5           5           8
  5         8           6           10
  6         13          7           16
}\modeltable

\pgfplotstableread{
  Time      {Data 1}  {Data 2}
  0         1.3       2.3
  1         2.6       3.6
  2         3.8       4.8
  3         7.9       5.9
  4         6.3       7.3
  5         7.5       6.5
  6         9.0       8.9
}\datatable

\begin{document}

  \begin{tikzpicture}

    \begin{groupplot}[
      xlabel={Time},
      ylabel={Amplitude},
      every axis title shift=0,
      legend to name=grouplegend,
      legend style={/tikz/every even column/.append style={column sep=0.5cm}}
     ]

      \pgfplotsinvokeforeach{1,2}{%
        \nextgroupplot[title=Data $#1$]

        % Models
        \foreach \y in {1, 2, 3} {
          \addplot [smooth, dashed, color=DarkRed]
            table[x index=0, y index=\y] {\modeltable};

          \pgfplotstablegetcolumnnamebyindex{\y}\of{\modeltable}\to{\colname}
          \addlegendentryexpanded{\colname}
        }

        % Data
        \addplot [only marks, mark=o]
          table[x index=0, y index=#1] {\datatable};
        \addlegendentry {Data}
      }

    \end{groupplot}

    \node (dummytitle) at ($(group c1r1.north)!0.5!(group c2r1.north)$)
      [above]{};
    \node (title) at (dummytitle.north)
      [above, yshift=\pgfkeysvalueof{/pgfplots/every axis title shift}]
      {Experimental Data};

    \node (legend) at ($(group c1r1.south)!0.5!(group c2r1.south)$)
      [below, yshift=-2\pgfkeysvalueof{/pgfplots/every axis title shift}]
      {\ref{grouplegend}};

  \end{tikzpicture}

\end{document}
share|improve this answer
    
Should the \addlegendentry{Model} line still be in the \foreach loop? –  sappjw Apr 18 '12 at 14:09
    
@sappjw: Oops, no, it should not. –  Jake Apr 18 '12 at 14:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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