# Stacked barplots and text labels in x-coordinate

I was trying to stack a groupplot, or was it grouping a stacked plot? However I was trying to get something like: With Excel it didn't seem to be a problem but when I tried adapting it with pgfplots I got something like: Why is there a seperation after the first three stacked parts? And how can I label the bars separately but also label thee of them to one site?

Is the groupplot command even the right one to approach to this "problem"?

MWE:

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots,pgfplotstable}
\usetikzlibrary{pgfplots.groupplots}
\pgfplotsset{every axis legend/.append style={at={(0.5,1.025)}, anchor=south,semithick,legend columns=3},width=0.9\textwidth,compat=1.4}

\definecolor{RYB1}{RGB}{102, 194, 165}
\definecolor{RYB2}{RGB}{252, 141, 98}
\definecolor{RYB3}{RGB}{141, 160, 203}
\definecolor{RYB4}{RGB}{231, 138, 195}
\definecolor{RYB5}{RGB}{166, 216, 84}
\definecolor{RYB6}{RGB}{255, 217, 47}
\definecolor{RYB7}{RGB}{229, 196, 148}
\definecolor{RYB8}{RGB}{179,179,179}

\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},
{RYB8!50!black,fill=RYB8},
}

Criterion   Komp        Komp+PV Sorp
abc         7000        7000        12000
def         7500        7500        7500
ghi         7500        7500        7500
jkl         1500        1500        2250
mno         2000        2000        2000
pqrs        0       0       8000
tuv         0       0       11600
wxyz        0       5000        0
}\Rapperswil

Criterion   Komp        Komp+PV Sorp
abc         7000        7000        12900
def         7500        7500        7500
ghi         8000        8000        8000
jkl         1500        1500        2250
mno         2000        2000        2000
pqrs        0       0       8000
tuv         0       0       15440
wxyz        0       6300        0
}\Palermo

Criterion   Komp        Komp+PV Sorp
abc         7000        7000        19000
def         7500        7500        7500
ghi         9000        9000        9000
jkl         1500        1500        2250
mno         2000        2000        2000
pqrs        0       0       8000
tuv         0       0       23000
wxyz        0       8400        0
}\Jeddah

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

\begin{document}

\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,
ybar stacked,
/pgf/bar shift=0pt,scale only axis,
width=0.74\textwidth/3,
height=0.5\textwidth,
ylabel=y-axis, ylabel style={text height=0.02\textwidth,inner ysep=0pt},
enlarge x limits=0.15,
ymin=0,
ymax=80000,
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 columns=4,
legend image code/.code={%
\draw[#1] (0cm,-0.1cm) rectangle (0.3cm,0.1cm);
}
]

\nextgroupplot[xlabel=Rapperswil, legend to name=grouplegend,]
\pgfplotsinvokeforeach  {0,...,7}{
\addplot table [ x expr=\coordindex, select row=#1, y=Komp] {\Rapperswil};
\addplot table [x expr=\coordindex, select row=#1, y=Komp+PV] {\Rapperswil};
\addplot table [x expr=\coordindex, select row=#1, y=Sorp] {\Rapperswil};
}

\nextgroupplot[xlabel=Palermo]
\pgfplotsinvokeforeach  {0,...,7}{
\addplot table [ x expr=\coordindex, select row=#1, y=Komp] {\Palermo};
\addplot table [x expr=\coordindex, select row=#1, y=Komp+PV] {\Palermo};
\addplot table [x expr=\coordindex, select row=#1, y=Sorp] {\Palermo};
}

\nextgroupplot[xlabel=Jeddah]
\pgfplotsinvokeforeach  {0,...,7}{
\addplot table [x expr=\coordindex, select row=#1, y=Sorp] {\Jeddah};
\addplot table [x expr=\coordindex, select row=#1, y=Komp+PV] {\Jeddah};
\addplot table [x expr=\coordindex, select row=#1, y=Sorp] {\Jeddah};
}

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

\end{document}


@ zeroth: yes, that's what I had in mind.

I also fitted my example, getting to:

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots,pgfplotstable}
\pgfplotsset{every axis legend/.append style={at={(0.5,-0.20)},anchor=north,legend columns=-1},width=0.9\textwidth,compat=1.4}

Criterion           a   b   c   d   e   f   g   h
Komp1           7000    7500    7500    1500    2000    0   0   0
Komp+PV1            7000    7500    7500    1500    2000    0   0   5000
Sorp1               12000   7500    7500    2250    2000    8000    11600   0
Komp2           7000    7500    8000    1500    2000    0   0   0
Komp+PV2            7000    7500    8000    1500    2000    0   0   6300
Sorp2               12900   7500    8000    2250    2000    8000    15440   0
Komp3           7000    7500    9000    1500    2000    0   0   0
Komp+PV3            7000    7500    9000    1500    2000    0   0   8400
Sorp3               19000   7500    9000    2250    2000    8000    23000   0
}\datatableA

\begin{document}

\begin{figure}[h]
\centering
\begin{tikzpicture}
\begin{axis}    [name=plot1,
ybar stacked,
width=10cm,
height=6.2cm,
xtick=data,
xlabel=plot1,]
\addplot table [x expr=\coordindex, y=a] {\datatableA};
\addplot table [x expr=\coordindex, y=b] {\datatableA};
\addplot table [x expr=\coordindex, y=c] {\datatableA};
\addplot table [x expr=\coordindex, y=d] {\datatableA};
\addplot table [x expr=\coordindex, y=e] {\datatableA};
\addplot table [x expr=\coordindex, y=f] {\datatableA};
\addplot table [x expr=\coordindex, y=g] {\datatableA};
\addplot table [x expr=\coordindex, y=h] {\datatableA};
\legend{a,b,c,d,e,f,g,h}
\end{axis}

\end{tikzpicture}
\end{figure}

\end{document}


(sorry for the load of useless commands in the first one)

Now my problem is still the same. Who can I group the first three bars, the second three and the last three ones with one label each?

-
you could help everyone answering your question if you made your example smaller. You don't need groupplots to reproduce it, neither does the package german interfere with your problem. Also narrow it down to 1 table, you dont need 3. Sorry if it sounds harsh. But this will help you in the long run. Also try to transpose your data. That should make it easier to parse instead of select row. –  zeroth Dec 15 '11 at 14:12
I have rolled back to the original version. You don't need to clear your question and I recommend you keep it. But if you wish to do so, you can always delete the question by using the delete option under the question. –  percusse Dec 15 '11 at 15:03
@Lorzen i think you need to explicitly tell which data you need stacked, which you need labelled by the city name and which you need not labelled at all. With my solution you can put the three next to each other and it will look just like the Excel plot. Which was your question (or so it seemed). –  zeroth Dec 15 '11 at 16:37
@zeroth The data should be exactliy labelled like in the excel example. I tried to work with your MWE but I still don't know where to put the groupplot command. Sorry but there are commands I didn't even know they where existing. –  Lorzen Dec 15 '11 at 17:00
@Lorzen i now consider the question answered. If in doubt of the commands please look in the manual under the specific key. There is plenty of information in the manual. Kind regards... –  zeroth Dec 15 '11 at 18:07

I thought that it was an interesting plot. So I will supply my answer.

1. Is the groupplot command even the right one to approach to this "problem"?
Yes, what groupplot does is simply letting them be side by side in an easier manor. Nothing more, nothing less. Every \nextgroupplot is effectively the same as an enclosed axis environment.

2. Why is there a seperation after the first three stacked parts?
Because you have x expr=\coordindex. This means that in the second loop of \pgfplotsinvokeforeach the x expr=1 and in the third x expr=2. Meaning a new column. If you try commenting ymax=80000 out you will see what i mean.

3. And how can I label the bars separately but also label three of them to one site?

## How to get it working

First of all, your data should be rearranged. Your x coordinate should be in the first column and then each site (abc, def,...) should be a new column.
This will allow you to more easy handle the data, without those pesky filters (if you can make it work without them it is often easier).

Thus your data has to be in this format:

\pgfplotstableread{
Criterion    abc   def   ghi   jkl   mno  pqrs    tuv  wxyz
Komp        7000  7500  7500  1500  2000     0      0     0
Komp+PV     7000  7500  7500  1500  2000     0      0  5000
Sorp       12000  7500  7500  2250  2000  8000  11600     0
}\Rapperswil


Once you have done that you need to tell pgfplots to use the Criterion column for x-tickmarks. This requires usage of keys: xticklabels from table={\Rapperswil}{Criterion} and xtick=data. Thus you do not need to pretype the x-data!

The final result becomes:

\documentclass{article}
\usepackage{pgfplots,pgfplotstable}
Criterion    abc   def   ghi   jkl   mno  pqrs    tuv  wxyz
Komp        7000  7500  7500  1500  2000     0      0     0
Komp+PV     7000  7500  7500  1500  2000     0      0  5000
Sorp       12000  7500  7500  2250  2000  8000  11600     0
}\Rapperswil

\begin{document}
\begin{tikzpicture}
\begin{axis}[ybar=0pt,
ybar stacked,bar shift=0pt,
xticklabels from table={\Rapperswil}{Criterion},
xtick=data,
legend style={at={(1.025,1.0)},anchor=north west},
xlabel=Rapperswil]
\pgfplotstableforeachcolumn\Rapperswil\as\col{%
\ifnum\pgfplotstablecol=0
\else
\edef\tmp{%
}%
\tmp
\fi
}
\end{axis}
\end{tikzpicture}
\end{document}


Notice that you need the \edef due to \pgfplotstableforeachcolumn not being fully expanded on loop exit.

## Groupplots

When you need to put it together with groupplots you are on the right track with your own code, however use y descriptions at=edge left instead of ylabels at=edge left. The former makes both labels and ticks on the edge left. While the latter only applies to ylabels.

An example of using groupplots is to do the following. If in doubt of what the key does, please look it up in the manual. I have added the second table. I will leave it as an easy exercise to add the last one!

\documentclass{article}
\usepackage{pgfplots,pgfplotstable}
\usetikzlibrary{pgfplots.groupplots}
Criterion    abc   def   ghi   jkl   mno  pqrs    tuv  wxyz
Komp        7000  7500  7500  1500  2000     0      0     0
Komp+PV     7000  7500  7500  1500  2000     0      0  5000
Sorp       12000  7500  7500  2250  2000  8000  11600     0
}\Rapperswil
Criterion    abc   def   ghi   jkl   mno  pqrs    tuv  wxyz
Komp        7000  7500  8000  1500  2000     0      0     0
Komp+PV     7000  7500  8000  1500  2000     0      0  6300
Sorp       12900  7500  8000  2250  2000  8000  15440     0
}\Palermo

\begin{document}
\begin{tikzpicture}
\begin{groupplot}[group style= {
columns=2,xlabels at=edge bottom,
y descriptions at=edge left,
horizontal sep=0cm,group name=plots,
},
ymin=0,ymax=6e4,enlarge x limits={abs=.5},
ybar,ybar stacked,
/pgf/bar shift=0pt,/pgf/bar width=1.5cm,
xlabel style={yshift=-2ex}, % make the xlabel further down from the ticks
xticklabels from table={\Rapperswil}{Criterion}, % use the ticklabels from the table as a tick mark
xtick=data,legend columns=1]
% This defines a new axis environment which will be filled with data from table \Rapperswil
\nextgroupplot[xlabel=Rapperswil,legend to name=grouplegend]
\pgfplotstableforeachcolumn\Rapperswil\as\col{%
\ifnum\pgfplotstablecol=0 % The first column is "Criterion" we do not need that one, skip
\else
\edef\tmp{%
}%
\tmp
\fi
}
% This defines a new axis environment which will be filled with data from table \Palermo
\nextgroupplot[xlabel=Palermo]
\pgfplotstableforeachcolumn\Palermo\as\col{%
\ifnum\pgfplotstablecol=0
\else
\edef\tmp{%
}%
\tmp
\fi
}
\end{groupplot}
% Draw the dashed lines below the plot
\draw[dashed] (plots c1r1.south west) -- ++(0,-1.5);
\draw[dashed] (plots c2r1.south west) -- ++(0,-1.5);
\draw[dashed] (plots c2r1.south east) -- ++(0,-1.5);
% This will make the legend at the right of the plot just like Excel
\node at (plots c2r1.east) [inner sep=0pt,anchor=west, xshift=.6cm] {\ref{grouplegend}};
\end{tikzpicture}

\end{document}

-
Sorry I missed your update –  Lorzen Dec 15 '11 at 16:01
@Lorzen you can check my edit by clicking the edited xx mins ago, there you will have all revisions available. –  zeroth Dec 15 '11 at 16:42