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.

In order to create a nice plot for the comparison of three different sites I'm using the groupplot command. Now for every site I have seven different criterias to compare. So far the plot looks like

enter image description here

so every site has his own color. BUT I would like to set the color for every criteria itself. That means the first bar in every group goes gray, the second bar in every group goes maybe pink, and so on...

The second thing to be mentioned is that every criteria gets his own legend entry. so far the legend would contain the three sites.

And... befor I forget: is there a way to let the whole tikz-picture have an width of 0.9\textwith

I hope my problem is clear and anyone can help.

the MWE is:

\documentclass{article}

\usepackage{pgfplots}
\pgfplotsset{compat=1.4}
\usetikzlibrary{pgfplots.groupplots}

\begin{document}

\begin{tikzpicture}
\begin{groupplot}
    [
        group style=
            {
            columns=3,
            xlabels at=edge bottom,
            ylabels at=edge left,
            },
        ybar,
        width=0.425\textwidth,
        height=.45\textwidth,
        ylabel=kWh,
        enlarge x limits=0.15,
        ymin=0,
        xtick=\empty,
        tickpos=left,
        scaled y ticks=base 10:-3
    ]

\nextgroupplot[xlabel=Rapperswil]
\addplot [fill=blue] coordinates{(1,3620) (2,2739)(3,3710)(4,714)(5,2997)(6,1589)(7,2122)};

\nextgroupplot[xlabel=Palermo]
\addplot [fill=red] coordinates{(1,15947) (2,15109)(3,16146)(4,9306)(5,6840)(6,4992)(7,11154)};

\nextgroupplot[xlabel=Jeddah]
\addplot [fill=green] coordinates{(1,42754) (2,42240)(3,40533)(4,28919)(5,11614)(6,11786)(7,28747)};

\end{groupplot}
\end{tikzpicture}

\end{document}
share|improve this question
add comment

1 Answer 1

up vote 26 down vote accepted

In order to colour each bar differently and make it appear with its own legend entry, each bar needs to be handled as its own plot, i.e. it needs its own \addplot ... command. Fortunately, you don't have to write \addplot ... seven times, but instead you can use \pgfplotsinvokeforeach {0,...,6} { \addplot ... }.

I would suggest you provide the data in a table, either in an external datafile or in a macro created using \pgfplotstableread. This makes it easier to loop over the data, and it makes your data more maintainable (the coordinate syntax becomes quite tedious for larger datasets).

To provide different colours for the bars, you can define a new cycle list using \pgfplotscreatecyclelist. In the example below, I've defined seven colours according to a Colorbrewer color scheme and used them to define a new cycle list.

To create one legend for all of the plots, you can use the key legend to name=<name>, which stores the legend in a \label, so you can create it somewhere else using \ref{<name>}. In this case, I put it below the center of the second axis, so it aligns nicely with the axes. If it was centered according to the page, it would look misaligned.

By default, the entries in horizontal legends are quite close together. I've inserted a bit more space using the approach described in How can I adjust the horizontal spacing between legend entries in PGFPlots?.

To make the whole plot take up a specified width, you have to do a few calculations, as described in the accepted answer to pgfplots: how can I scale to text width?. You have to specify the plot width with the key scale only axis activated, the space taken up by the y tick labels and the y axis label, and the space between the groupplots, and these dimensions have to add up to your desired overall width. In this case, I set the space between the plots to 0.05\textwidth (so 0.1\texwidth in total, because there are three plots), the space for the leftmost ytick labels to 0.035\textwidth with an offset of 0.005\textwidth, so 0.04\textwidth overall, the space for the y label to 0.02\textwidth, and the width of the axes to 0.74\textwidth/3. This adds up to 0.74\textwidth/3 * 3 + 0.02\textwidth + 0.04\textwidth + 0.1\textwidth = 0.9\textwidth. Try setting the axis width to 0.84\textwidth/3: This will make the whole environment exactly \texwidth wide.

\documentclass{article}
\usepackage{lipsum}
\usepackage{pgfplots,pgfplotstable}
\pgfplotsset{compat=1.4}
\usetikzlibrary{pgfplots.groupplots}

\pgfplotstableread{
Criterion   Rapperswil  Palermo Jeddah
Turquoise       3620        15749       42754
Yellow      2739        15109       42240
Purple      3710        16146       40533
Red           714         9306      28919
Blue        2997          6840  11614
Orange      1589          4992  11786
Green       2122        11154   28747
}\datatable

\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{
    select row/.style={
        x filter/.code={\ifnum\coordindex=#1\else\def\pgfmathresult{}\fi}
    }
}

\begin{document}

\lipsum[1]

\begin{figure}[hbt!]
\centering
\begin{tikzpicture}
\begin{groupplot}
    [
        group style=
            {
            columns=3,
            xlabels at=edge bottom,
            ylabels at=edge left,
            horizontal sep=0.05\textwidth, group name=plots
            },
        ybar=0pt,
        /pgf/bar shift=0pt,scale only axis,
        width=0.74\textwidth/3,
        yticklabel style={text width=0.035\textwidth, align=right, inner xsep=0pt, xshift=-0.005\textwidth},
        ylabel=kWh, ylabel style={text height=0.02\textwidth,inner ysep=0pt},
        enlarge x limits=0.15,
        ymin=0,
        xtick=\empty,
        tickpos=left,
        scaled y ticks=base 10:-3,
        cycle list name=colorbrewer-RYB,
        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);
        }
    ]

\nextgroupplot[xlabel=Rapperswil, legend to name=grouplegend,]
\pgfplotsinvokeforeach  {0,...,6}{
    \addplot table [ x expr=\coordindex, select row=#1, y=Rapperswil] {\datatable};
    \addlegendentry {\pgfplotstablegetelem{#1}{Criterion}\of\datatable \pgfplotsretval}
}

\nextgroupplot[xlabel=Palermo]
\pgfplotsinvokeforeach  {0,...,6}{
    \addplot table [x expr=\coordindex, select row=#1, y=Palermo] {\datatable};
}

\nextgroupplot[xlabel=Jeddah]
\pgfplotsinvokeforeach  {0,...,6}{
    \addplot table [x expr=\coordindex, select row=#1, y=Jeddah] {\datatable};
}

\end{groupplot}
\node at (plots c2r1.south) [inner sep=0pt,anchor=north, yshift=-5ex] {\ref{grouplegend}};
\end{tikzpicture}
\end{figure}

\lipsum[2]
\end{document}
share|improve this answer
add comment

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.