8

I want to cycle colours for each x co-ordinate in a bar plot. Is it possible? For instance, in this example I want each metric to appear in a different colour.

This question Colors and legend in groupplots/barplot does something very similar except that in my case for every loop, I want to add two bars (one light shade and one dark shade colour).

\documentclass{article}
\usepackage[hscale=0.9]{geometry}
\usepackage{tikz}
\usepackage{pgfplots}
\usetikzlibrary{calc,shapes.geometric,arrows,fit,matrix,positioning,pgfplots.groupplots,trees,patterns}

\begin{document}
\begin{figure*}
\begin{tikzpicture}
\begin{groupplot}[group style={group size= 3 by 2,xticklabels at=edge bottom},height=5cm,width=5cm,ybar=1pt,xtick=data,tick label style={font=\scriptsize},x tick label style={rotate=45,anchor=east}
                                    ,symbolic x coords={metric1,metric2,metric3,metric4,metric5,metric6}, ylabel style={align=center}]
    \nextgroupplot[title=a,ylabel={set1}, bar width=5pt]
        \addplot[fill=blue!40]  table[x=metric,y=a1,col sep=space]  {colourData1.csv};
        \addplot[fill=blue!80]  table[x=metric,y=a2,col sep=space]  {colourData1.csv};
    \nextgroupplot[title=b,bar width=5pt]
        \addplot[fill=blue!40]  table[x=metric,y=b1,col sep=space]  {colourData1.csv};
        \addplot[fill=blue!80]  table[x=metric,y=b2,col sep=space]  {colourData1.csv};
    \nextgroupplot[title=c,bar width=5pt]
        \addplot[fill=blue!40]  table[x=metric,y=c1,col sep=space]  {colourData1.csv};
        \addplot[fill=blue!80]  table[x=metric,y=c2,col sep=space]  {colourData1.csv};
    \coordinate (mtop) at (rel axis cs:0,1);% coordinate at top of the first plot

    \nextgroupplot[ylabel={set2}, bar width=5pt]
        \addplot[fill=blue!40]  table[x=metric,y=a1,col sep=space]  {colourData2.csv};
        \addplot[fill=blue!80]  table[x=metric,y=a2,col sep=space]  {colourData2.csv};
    \nextgroupplot[bar width=5pt]
        \addplot[fill=blue!40]  table[x=metric,y=b1,col sep=space]  {colourData2.csv};
        \addplot[fill=blue!80]  table[x=metric,y=b2,col sep=space]  {colourData2.csv};
    \nextgroupplot[bar width=5pt]
        \addplot[fill=blue!40]  table[x=metric,y=c1,col sep=space]  {colourData2.csv};
        \addplot[fill=blue!80]  table[x=metric,y=c2,col sep=space]  {colourData2.csv};
    \coordinate (mbot) at (rel axis cs:1,0);% coordinate at bottom of the last plot
\end{groupplot}

\path (mtop-|current bounding box.west)-- node[anchor=south,rotate=90,yshift=-0.9cm] {\small Common} (mbot-|current bounding box.west);
\end{tikzpicture}
\caption{group plot with each plot in a different colour}
\label{fig:metrics}
\end{figure*}

\end{document}

enter image description here

Update

For a single plot inside this group plot, there are six metrics. For each metric there are two bars. For example in the top left plot, for all 6 metrics, a1 and a2 are plotted. Similarly for the bottom right plot c1 and c2 are plotted.

I would like to have each metric plotted in a different colour. But the two bars for a metric should be plotted with a dark and light shade of same colour.

Note: I'm ok with transposing the input data if that is easier to plot.

colourData1.csv:

metric  a1  a2  b1  b2  c1  c2
metric1 30  60  50  100 50  100
metric2 40  80  60  120 25  50
metric3 50  100 80  160 60  120
metric4 60  120 60  120 89  178
metric5 70  140 25  50  20  40
metric6 80  160 30  60  23  46

colourData2.csv is a clone of colourData1.csv

arunmoezhi
  • 1,270
  • Your code can't be compiled due to dependence on a file not provided. – cfr Dec 26 '15 at 01:31
  • Ahh. You are right. I did not provide colourData2.csv. It can be a clone of colourData1.csv – arunmoezhi Dec 26 '15 at 01:33
  • 1
    It isn't really clear to me what you want to do. Do you want a different colour for each column pair within two plots? Or do you want different colours for each pair of plots? If the former, your data input is quite differently arranged from that in the linked question but you don't make that clear. – cfr Dec 26 '15 at 02:16
  • I've updated the question – arunmoezhi Dec 26 '15 at 16:02
  • As I see, you manually defines colors of bars. So why you not change their colors on the same way, for example the first graph is in blue, the second in red etc? Or I miss something in your question? – Zarko Dec 26 '15 at 16:11

1 Answers1

4

This is just a version of the aswer you linked to tailored to fit you. A bit of trickery (max space between ticks) was necessary to make the ticks on the x axis behave.

\documentclass[tikz, border=1cm]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{pgfplots.groupplots}

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

\pgfplotscreateplotcyclelist{yay-rainbow}{
{black!60!red   ,fill=white!00!red   },
{black!60!red   ,fill=white!60!red   },
{black!60!orange,fill=white!00!orange},
{black!60!orange,fill=white!60!orange},
{black!60!yellow,fill=white!00!yellow},
{black!60!yellow,fill=white!60!yellow},
{black!60!green ,fill=white!00!green },
{black!60!green ,fill=white!60!green },
{black!60!cyan  ,fill=white!00!cyan  },
{black!60!cyan  ,fill=white!60!cyan  },
{black!60!violet,fill=white!00!violet},
{black!60!violet,fill=white!60!violet}}

\def\twinplot#1#2{
  \pgfplotsforeachungrouped \row in {0,...,5}{
    \pgfplotsforeachungrouped \col in {1,...,2}{
      \edef\justplotit{
        \noexpand\addplot+[bar shift=(\col-1.5)*\pgfplotbarwidth]
          table [x=metric, select row=\row, y=#1\col] {#2};}
      \justplotit
    }
  }
}


\begin{document}
\begin{tikzpicture}
\begin{groupplot}
  [
    group style={group size= 3 by 2,xticklabels at=edge bottom},
    height=5cm,
    width=5cm,
    ybar=1pt,
    tick label style={font=\scriptsize},
    x tick label style={rotate=45,anchor=east},
    symbolic x coords={metric1,metric2,metric3,metric4,metric5,metric6},
    ylabel style={align=center},
    cycle list name=yay-rainbow,
    max space between ticks=15,
  ]

  \pgfkeys{/pgf/bar width=5pt}

  \nextgroupplot [title=a, ylabel=set1] \twinplot{a}{colourData1.csv}
  \nextgroupplot [title=b,            ] \twinplot{b}{colourData1.csv}
  \nextgroupplot [title=c,            ] \twinplot{c}{colourData1.csv}

  \coordinate (mtop) at (rel axis cs:0,1);

  \nextgroupplot [         ylabel=set1] \twinplot{a}{colourData2.csv}
  \nextgroupplot [                    ] \twinplot{b}{colourData2.csv}
  \nextgroupplot [                    ] \twinplot{c}{colourData2.csv}

  \coordinate (mbot) at (rel axis cs:1,0);

\end{groupplot}

\path (mtop-|current bounding box.west) --
  node [anchor=south, rotate=90, yshift=-0.9cm] {\small Common}
  (mbot-|current bounding box.west);

\end{tikzpicture}
\end{document}

rainbowz

  • Thank you. Can you please add some explanations to your definition of twinplots. I understand the two for loops. But why the bar shift? Also why the need for max space between ticks – arunmoezhi Dec 30 '15 at 17:36
  • 1
    Each multicolor twelve-bar plot is actually twelve single-colour single-bar plots. When you overlay bar plots pgfplots tries to be smart by offsetting the bars. The default however makes no sense in this case and you must manually nudge odd ones to the left and even ones to the right, hence the explicit bar shift. Furthermore, xticks=data determines the ticks range using just the first plot: i.e. only metric1. I removed it so the ticks cover the axis and set max space between ticks to give them the right density. 15 is a number i made up that just happens to work. – Paolo Brasolin Dec 30 '15 at 17:47