2

I have a file with multiple columns, of which I create scatter plots where positions are given from column 1 vs column 2, while the mark color is based on column 3. I now wish to automatically create a legend with an entry for each color.

The following solution works for a limited number of colors (6-7). It uses a colormap for the dots in the scatter plot and a color cycle list, with equal colors as in the colormap, for the legend images.

Question: How do I generalize it to use with more dots than colors? This would require to use the colormap to draw the legend images instead of the cycle list. If this was possible, one could also use predefined colormaps, instead of defining everything anew.

I think the problem is, that the \addlegendentry in the loop is unable to retain the color of the current scattered mark, otherwise the solution would be a lot easier.

\documentclass{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepackage{filecontents}
\pgfplotsset{compat=newest}

\usetikzlibrary{pgfplots.groupplots}


\begin{filecontents}{data.out}
0 1  2
1 3  4
2 5  6
3 7  8
4 11 12
5 13 14
\end{filecontents}


\pgfplotstableread{data.out}\datatable

\pgfplotsset{
    select row/.style={
        x filter/.code={\ifnum\coordindex=#1\else\def\pgfmathresult{}\fi}
    }
}


\definecolor{RYB1}{RGB}{141, 211, 199}
\definecolor{RYB2}{RGB}{255, 255, 179}
\definecolor{RYB3}{RGB}{190, 186, 218}
\definecolor{RYB4}{RGB}{251, 128, 114}
\definecolor{RYB5}{RGB}{128, 177, 211}
\definecolor{RYB6}{RGB}{253, 180, 98}
\definecolor{RYB7}{RGB}{179, 222, 105}

\pgfplotscreateplotcyclelist{colorbrewer-RYB}{
{RYB1!50!black,fill=RYB1},
{RYB2!50!black,fill=RYB2},
{RYB3!50!black,fill=RYB3},
{RYB4!50!black,fill=RYB4},
{RYB5!50!black,fill=RYB5},
{RYB6!50!black,fill=RYB6},
%{RYB7!50!black,fill=RYB7},
}

\pgfplotsset{colormap={MyRYB}{
    rgb255=(141, 211, 199)
    rgb255=(255, 255, 179)
    rgb255=(190, 186, 218)
    rgb255=(251, 128, 114)
    rgb255=(128, 177, 211)
    rgb255=(253, 180, 98)
%    rgb255=(179, 222, 105)
  }
}


\begin{document}

\begin{tikzpicture}
  \begin{groupplot}[
    group style={
      group name=myplot,
      group size=2 by 1,
      horizontal sep=60pt,
    },
    legend pos=outer north east,
    % colormap/bluered,
    colormap name={MyRYB},
    scatter/use mapped color=
    {draw=black,fill=mapped color},
    cycle list name=colorbrewer-RYB,
    ]

    \nextgroupplot[
    legend to name=grouplegend,
    legend columns=-1,
    legend style={draw=none, /tikz/every even column/.append style={column sep=5pt}},
    legend image code/.code={%
      \draw[#1] (0cm,-0.1cm) rectangle (0.3cm,0.1cm);
    },
    ]


    \pgfplotsinvokeforeach  {0,...,6}{
    \addplot+[scatter,scatter src=\thisrowno{2},thick]
    table [ x index={0}, select row=#1, y index={1}] {data.out};
    \addlegendentry {\pgfplotstablegetelem{#1}{2}\of\datatable \pgfplotsretval}
    }

    \addplot[mark=none,color=red,thick,solid,forget plot]
    table [x index={0},y index={1}] {data.out};


    \addplot[scatter,scatter src=\thisrowno{2},mark=square*,color=blue,thick,solid,forget plot]
    table [x expr=\thisrowno{0}+1,y index={1}] {data.out};

    \nextgroupplot

    \addlegendimage{mark=*,mark options={draw=black,fill=white},color=red,thick,solid}
    \addlegendentry{$a$}
    \addlegendimage{mark=square*,mark options={draw=black,fill=white},color=blue,thick,solid}
    \addlegendentry{$b$}
    \addplot[scatter,scatter src=\thisrowno{2},mark=*,color=red,thick,solid]
    table [x index={0},y index={1}] {data.out};

    \addplot[scatter,scatter src=\thisrowno{2},mark=square*,color=blue,thick,solid]
    table [x expr=\thisrowno{0}+1,y index={1}] {data.out};


  \end{groupplot}


  \node  at ($(myplot c1r1.south)!0.5!(myplot c2r1.south)$)
  [inner sep=0pt,anchor=north, yshift=-5ex]
  {\ref{grouplegend}};


\end{tikzpicture}

\end{document}

Output

The idea is copied from Jake's answer here.

Jost
  • 1,337
  • I am not totally sure what you want to achieve. If you think that the colors in the plot correspond to the colors in the legend, then you are wrong. You can check this by e.g. changing the 14 in your data file to 140. So what exactly do you want to achieve? Use the colors of the cycle list or the colors of the colorbar (in your example with my suggested change)? Are in your real plot also the legend entries just the numbers of thisrowno{2}? – Stefan Pinnow Nov 12 '16 at 22:54

0 Answers0