1

Inspired by this question, pgfplot/tikz stacked bar chart, I've been trying to create a stacked bar chart with numbers at the end of the stacked bars. However, the location of nodes near coords was changed in pgfplot v1.9 to be over the centre of the bar segment. I've tried several things including setting nodes near coords style={text depth=2cm} but this obviously doesn't move with the data values. I've also tried making a 'topper' series, but this isn't the greatest solution IMO, and messes with reverse legend=true (though, this could be fixed with a more manually specified legend).

Would work pre 1.9:

\documentclass{standalone}
\usepackage{tikz,pgfplots,pgfplotstable}
\pgfplotsset{compat=1.9} % set to 1.8 to get old behaviour

\begin{document}

    \pgfplotstableread{
Label series1 series2 series3
A 21.87797  5.566584 24.85545
B 20.93009  7.937881 24.33203
C 20.41148 21.126529 27.56199
D 26.83072 23.823827 28.94545
    }\testdata

    \begin{tikzpicture}

    \begin{axis}[
        ybar stacked,
        ymin=0,
        ymax=100,
        xtick=data,
        legend style={cells={anchor=west}, legend pos=north west},
        reverse legend=true,
        xticklabels from table={\testdata}{Label},
        xticklabel style={text width=2cm,align=center},
    ]
    \addplot [fill=green!80] table [y=series1, meta=Label, x expr=\coordindex] {\testdata};
    \addlegendentry{series1}
    \addplot [fill=blue!60] table [y=series2, meta=Label, x expr=\coordindex] {\testdata};
    \addlegendentry{series2}
    \addplot [fill=red!60,nodes near coords,point meta=y] table [y=series3, meta=Label, x expr=\coordindex] {\testdata};
    \addlegendentry{series3}

    \end{axis}
    \end{tikzpicture}
\end{document}

stacked bar chart with total over last segment

'topper' solution:

\documentclass{standalone}
\usepackage{tikz,pgfplots,pgfplotstable}
\pgfplotsset{compat=1.9} % set to 1.8 to get old behaviour

\begin{document}

    \pgfplotstableread{
Label series1 series2 series3 topper
A 21.87797  5.566584 24.85545 0.001
B 20.93009  7.937881 24.33203 0.001
C 20.41148 21.126529 27.56199 0.001
D 26.83072 23.823827 28.94545 0.001
    }\testdata

    \begin{tikzpicture}

    \begin{axis}[
        ybar stacked,
        ymin=0,
        ymax=100,
        xtick=data,
        legend style={cells={anchor=west}, legend pos=north west},
        reverse legend=true, % set to false to get correct display, but I'd like to have this true
        xticklabels from table={\testdata}{Label},
        xticklabel style={text width=2cm,align=center},
    ]
    \addplot [fill=green!80] table [y=series1, meta=Label, x expr=\coordindex] {\testdata};
    \addlegendentry{series1}
    \addplot [fill=blue!60] table [y=series2, meta=Label, x expr=\coordindex] {\testdata};
    \addlegendentry{series2}
    \addplot [fill=red!60] table [y=series3, meta=Label, x expr=\coordindex] {\testdata};
    \addlegendentry{series3}
    \addplot [nodes near coords,point meta=y,nodes near coords style={anchor=south}] table [y=topper, meta=Label, x expr=\coordindex] {\testdata};

    \end{axis}
    \end{tikzpicture}
\end{document}

stacked bar chart with total above last segment, using topper solution

  • Did my answer answer your question or was it at least helpful? If yes, please consider upvoting (by clicking on the arrows next to the score) and/or marking it as the accepted answer (by clicking on the checkmark ✓). – Stefan Pinnow Jan 25 '18 at 19:03
2

The simplest solution would be to set the compat/bar nodes level back to 1.8. By doing that you can use all new features set by compat level except for the explicitly single set compat/... features.

% used PGFPlots v1.15
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
    \pgfplotsset{
        compat=1.9,
        compat/bar nodes=1.8,
    }
    \pgfplotstableread{
        Label series1 series2 series3
        A 21.87797  5.566584 24.85545
        B 20.93009  7.937881 24.33203
        C 20.41148 21.126529 27.56199
        D 26.83072 23.823827 28.94545
    }\testdata
\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        ybar stacked,
        ymin=0,
        ymax=100,
        xtick=data,
        legend style={
            cells={anchor=west},
            legend pos=north west,
        },
        reverse legend=true,
        xticklabels from table={\testdata}{Label},
        xticklabel style={text width=2cm,align=center},
    ]
        \addplot [fill=green!80]
            table [y=series1, meta=Label, x expr=\coordindex]
                {\testdata};
                    \addlegendentry{series1}
        \addplot [fill=blue!60]
            table [y=series2, meta=Label, x expr=\coordindex]
                {\testdata};
                    \addlegendentry{series2}
        \addplot [fill=red!60,nodes near coords,point meta=y]
            table [y=series3, meta=Label, x expr=\coordindex]
                {\testdata};
                    \addlegendentry{series3}
    \end{axis}
\end{tikzpicture}
\end{document}

image showing the result of above code

1

The "topper" solution can be refined a little, to remove the requirement that you must have a table column with the near-zero data by setting the y expr key to a small constant instead. The legend is still broken, though.

\documentclass{standalone}
\usepackage{biblatex} % so can use same script/recipie as actual documents
\usepackage{tikz,pgfplots,pgfplotstable}

\begin{document}

    \pgfplotstableread{
Label series1 series2 series3
A 21.87797  5.566584 24.85545
B 20.93009  7.937881 24.33203
C 20.41148 21.126529 27.56199
D 26.83072 23.823827 28.94545
    }\testdata

    \begin{tikzpicture}

    \begin{axis}[
        ybar stacked,
        ymin=0,
        ymax=100,
        xtick=data,
        legend style={cells={anchor=west}, legend pos=north west},
        reverse legend=true, % set to false to get correct display, but I'd like to have this true
        xticklabels from table={\testdata}{Label},
        xticklabel style={text width=2cm,align=center},
    ]
    \addplot [fill=green!80] table [y=series1, meta=Label, x expr=\coordindex] {\testdata};
    \addlegendentry{series1}
    \addplot [fill=blue!60] table [y=series2, meta=Label, x expr=\coordindex] {\testdata};
    \addlegendentry{series2}
    \addplot [fill=red!60] table [y=series3, meta=Label, x expr=\coordindex] {\testdata};
    \addlegendentry{series3}
    \addplot [
        ybar, % this makes it show the total for some reason
        nodes near coords,
        nodes near coords style={%
            anchor=south,%
        },
    ] table [ y expr=0.00001, x expr=\coordindex] {\testdata};

    \end{axis}
    \end{tikzpicture}
\end{document}

resulting plot, looks correct with labels above stacked bars, except the legend which shows the wrong colours

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.