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.

I was trying to stack a groupplot, or was it grouping a stacked plot? However I was trying to get something like:

enter image description here

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

enter image description here

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}
\pgfplotsset{width=0.3\textwidth,compat=newest}

\pgfplotstableread{
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

\pgfplotstableread{
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

\pgfplotstableread{
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};
    \addlegendentry {\pgfplotstablegetelem{#1}{cr}\of \first \pgfplotsretval}
}

\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}
share|improve this question
1  
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

1 Answer 1

up vote 14 down vote accepted

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

To answer some of your questions:

  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?
    I do not quite follow your question here, but I think that my answer has a solution to it, otherwise please reply.

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

\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{%
            \noexpand\addplot table [x expr=\noexpand\coordindex,y=\col] {\noexpand\Rapperswil};
            \noexpand\addlegendentry {\col}%
        }%
        \tmp
        \fi
    }
  \end{axis}
\end{tikzpicture}
\end{document}

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

output of code

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}
\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
\pgfplotstableread{
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{%
            \noexpand\addplot table [x expr=\noexpand\coordindex,y=\col] {\noexpand\Rapperswil};
            \noexpand\addlegendentry {\col}%
        }%
        \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{%
            \noexpand\addplot table [x expr=\noexpand\coordindex,y=\col] {\noexpand\Palermo};
        }%
        \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}
share|improve this answer
    
@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

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.