18

I tried a while to create that kind of chart with ybar but it's a mix between "ybar stacked" and "ybar". How can I do that?

I tried this way but with no great results:

\begin{tikzpicture}

\begin{axis}[ybar stacked, symbolic x coords={Duracem, Technocem, Alipre, Duracem, 
Technocem, Duracem, Technocem, Alipre, Duracem, Technocem, Duracem, Technocem, Alipre, 
Duracem, Technocem, Duracem, Technocem, Alipre, Duracem, Technocem, Duracem, Technocem,
Alipre, Duracem, Technocem}]

\addplot coordinates {(Duracem,47.2) (Technocem,39) (Alipre,28) (Duracem,16.2)
(Technocem,15) (Duracem,40) (Technocem,16.4) (Alipre,28) (Duracem,33) (Technocem,15) 
(Duracem,89) (Technocem,96)(Alipre,49.6) (Duracem,22.9) (Technocem,15.1) (Duracem,105) 
(Technocem,83) (Alipre,47) (Duracem,19.5)(Technocem,24.4)};

\end{axis}
\end{tikzpicture}

The chart wanted: The chart as it should look like

1 Answer 1

30

You can use a normal ybar stacked plot for this.

For complicated plots like this, it makes sense to provide the data as a table using \pgfplotstableread{< data >}{<\macroname>}.

For getting the grouping right, I've introduced a column X that contains the horizontal positions of the plots.

The labels of the plots can be provided using xtick=data, xticklabels from table={\datatable}{Name}. The key xtick data makes sure that each bar gets a label.

For placing group labels, I've defined a new key draw group line={<group column>}{<group value>}{<group label>}{<vertical offset>}{<line extension>}. This key could certainly be improved by using styles to make it more comfortable to use, but it works quite well for this application.

\documentclass{article}
\usepackage{pgfplots, pgfplotstable}


\newcounter{groupcount}
\pgfplotsset{
    draw group line/.style n args={5}{
        after end axis/.append code={
            \setcounter{groupcount}{0}
            \pgfplotstableforeachcolumnelement{#1}\of\datatable\as\cell{%
                \def\temp{#2}
                \ifx\temp\cell
                    \ifnum\thegroupcount=0
                        \stepcounter{groupcount}
                        \pgfplotstablegetelem{\pgfplotstablerow}{X}\of\datatable
                        \coordinate [yshift=#4] (startgroup) at (axis cs:\pgfplotsretval,0);
                    \else
                        \pgfplotstablegetelem{\pgfplotstablerow}{X}\of\datatable
                        \coordinate [yshift=#4] (endgroup) at (axis cs:\pgfplotsretval,0);
                    \fi
                \else
                    \ifnum\thegroupcount=1
                        \setcounter{groupcount}{0}
                        \draw [
                            shorten >=-#5,
                            shorten <=-#5
                        ] (startgroup) -- node [anchor=base, yshift=0.5ex] {#3} (endgroup);
                    \fi
                \fi
            }
            \ifnum\thegroupcount=1
                        \setcounter{groupcount}{0}
                        \draw [
                            shorten >=-#5,
                            shorten <=-#5
                        ] (startgroup) -- node [anchor=base, yshift=0.5ex] {#3} (endgroup);
            \fi
        }
    }
}

\begin{document}
\begin{tikzpicture}
\pgfplotstableread{
X   Gp  C1  C2  Name        Zn      Pb
1   1A  0.2 3   Duracem     47.2    12
2   1A  0.2 3   Technocem   39      11
3   1A  0.2 3   Alipre      28      13
5   1A  0.2 8   Duracem     16.2    12
6   1A  0.2 8   Technocem   15      15
8   1A  0.5 3   Duracem     89      17
9   1A  0.5 3   Technocem   96      19
10  1A  0.5 3   Alipre      49.6    20
12  1A  0.5 8   Duracem     22.9    12
13  1A  0.5 8   Technocem   15.1    11
15  2A  0.2 3   Duracem     105     10
16  2A  0.2 3   Technocem   83      17  
17  2A  0.2 3   Alipre      47      20
19  2A  0.2 8   Duracem     19.5    21
20  2A  0.2 8   Technocem   24.4    8
}\datatable

\begin{axis}[
    axis lines*=left, ymajorgrids,
    width=12cm, height=6cm,
    ymin=0,
    ybar stacked,
    bar width=8pt,
    xtick=data,
    xticklabels from table={\datatable}{Name},
    xticklabel style={rotate=90,xshift=-10ex,anchor=mid east},
    draw group line={C2}{3}{3\,\%}{-10ex}{4pt},
    draw group line={C2}{8}{8\,\%}{-10ex}{4pt},
    draw group line={C1}{0.2}{0.2\,\%}{-7ex}{5pt},
    draw group line={C1}{0.5}{0.5\,\%}{-7ex}{5pt},
    draw group line={Gp}{1A}{1A}{-4ex}{7pt},
    draw group line={Gp}{2A}{2A}{-4ex}{7pt},
    after end axis/.append code={
        \path [anchor=base east, yshift=0.5ex]
            (rel axis cs:0,0) node [yshift=-10ex] {Conc 1}
            (rel axis cs:0,0) node [yshift=-7ex] {Conc 2}
            (rel axis cs:0,0) node [yshift=-4ex] {Group};
    }
]

\addplot table [x=X, y=Zn] {\datatable}; \addlegendentry{Zn}
\addplot table [x=X, y=Pb] {\datatable}; \addlegendentry{Pb}

\end{axis}
\end{tikzpicture}


\end{document} 
3
  • As always -- AWESOME May 12, 2012 at 20:11
  • Like Marco said Awesome!! I don't have the reputation to give you a "usefull point" for your answer but it is really what i wanted an your answer was in only an hour time! Really great!
    – Rave
    May 12, 2012 at 21:45
  • @Jake: this was really helpful for me! I have a tip for everyone using this draw group line style with a graph, where ymin is set to != 0 - just change the coordinates set here \coordinate [yshift=#4] (startgroup) at (axis cs:\pgfplotsretval,0); to \coordinate [yshift=#4] (startgroup) at (axis cs:\pgfplotsretval,\pgfkeysvalueof{/pgfplots/ymin}); and the same for (endgroup) and your grouplines will appear where you want them to.
    – Garonenur
    Oct 16, 2015 at 14:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .