# Stacked barplots/groupplots with 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:

The ybar stacked option works quite nice here. But when I try to adapt it to a groupplot I run into some problems. The goal is to create three groups with a xlabel each. In each group each bar should also have its own xticklabel. The MWE so far gives this

Why is there a seperation after the first three stacked parts? And how can I label the bars separately but also label the groups?

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

MWE:

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots,pgfplotstable}
\usetikzlibrary{pgfplots.groupplots}

cr  Fii Faa Foo
abc 10  20  30
def 5   5   5
ghi 7   7   7
jkl 1.5 1.5 2.5
mno 2   2   2
pqrs    0   0   8
tuv 0   0   1.16
wxyz    0   5   0
}\first

cr  Fii Faa Foo
abc 7   7   12.9
def 7.5 7.5 7.5
ghi 8   8   8
jkl 1.5 1.5 2.25
mno 2   2   2
pqrs    0   0   8
tuv 0   0   1.544
wxyz    0   6.3 0
}\second

cr  Fii Faa Foo
abc 7   7   19
def 7.5 7.5 7.5
ghi 9   9   9
jkl 1.5 1.5 2.25
mno 2   2   2
pqrs    0   0   8
tuv 0   0   23
wxyz    0   8.4 0
}\third

\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,
ylabels at=edge left,
group name=plots},
ybar stacked,
scale only axis,
ylabel=y-axis,
ymin=0,
ymax=150,
height=0.5\textwidth,
xtick=\empty,
legend columns=-1,
legend image code/.code={%
\draw[#1] (0cm,-0.1cm) rectangle (0.3cm,0.1cm);
}
]

\nextgroupplot[xlabel=Item 1, legend to name=grouplegend,]
\pgfplotsinvokeforeach  {0,...,7}{
\addplot table [x expr=\coordindex, select row=#1, y=Fii] {\first};
\addplot table [x expr=\coordindex, select row=#1, y=Faa] {\first};
\addplot table [x expr=\coordindex, select row=#1, y=Foo] {\first};
}

\nextgroupplot[xlabel=Item 2]
\pgfplotsinvokeforeach  {0,...,7}{
\addplot table [x expr=\coordindex, select row=#1, y=Fii] {\second};
\addplot table [x expr=\coordindex, select row=#1, y=Faa] {\second};
\addplot table [x expr=\coordindex, select row=#1, y=Foo] {\second};
}

\nextgroupplot[xlabel=Item 3]
\pgfplotsinvokeforeach  {0,...,7}{
\addplot table [x expr=\coordindex, select row=#1, y=Fii] {\third};
\addplot table [x expr=\coordindex, select row=#1, y=Faa] {\third};
\addplot table [x expr=\coordindex, select row=#1, y=Foo] {\third};
}

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

\end{document}

-
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}

-
@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