3

Here is a MWE

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots, pgfplotstable}
\usepackage{filecontents}

\pgfplotsset{compat=1.5.1}

\begin{filecontents}{datatable.csv}
27  47
12  21
39  69
12 17
17 23
67 69
\end{filecontents}


\pgfplotstableset{
    create on use/accumyprev/.style={
        create col/expr={\prevrow{0}+\prevrow{1}+\pgfmathaccuma}
    }
}


% Style for centering the labels
\makeatletter
\pgfplotsset{
    centered nodes near coords/.style={
    calculate offset/.code={
        \pgfkeys{/pgf/fpu=true,/pgf/fpu/output format=fixed}
        \pgfmathsetmacro\testmacro{(\pgfplotspointmeta*10^\pgfplots@data@scale@trafo@EXPONENT@y)/2*\pgfplots@y@veclength)}
        \pgfkeys{/pgf/fpu=false}
    },
    every node near coord/.style={
        /pgfplots/calculate offset,
        yshift=-\testmacro,
        black,
        font=\scriptsize,
    },
    nodes near coords align=center
    }
}
\makeatother


\begin{document}

\begin{tikzpicture}
\begin{axis}[
width  = 0.85*\textwidth,
        height = 8cm,
    no markers,
    ybar stacked,
    bar width = 20pt,
    ymin=0,
    point meta=explicit,
    centered nodes near coords, 
    axis lines*=left,
    xtick=data,
    major tick length=0pt,
    xticklabels={
    2014\\ GDP,
        Business \\as \\ usual \\growth,
        Total \\2025 \\ business-\\as-usual \\l GDP,
        Increm-\\ental \\ best-\\in-region\\  GDP\\ in 2025,
        additional\\ GDP \\ in full\\-potential \\ scenarios in\\  2025,
        Total \\2025\\ business-\\as-usual\\ GDP,
    },
    xticklabel style={font=\small, text width=4cm, align=center},
    enlarge x limits=-0.85,
    ytick=\empty,
    y axis line style={opacity=0},
    ylabel style={font=\small},
    axis on top
]

% The first plot sets the "baseline": Uses the sum of all previous y values, except for the last bar, where it becomes 0
\addplot +[
    y filter/.code={\ifnum\coordindex>2 \def\pgfmathresult{0}\fi},
    draw=none,
    fill=none
] table [x expr=\coordindex, y=accumyprev] {datatable.csv};

% The lower bound
\addplot +[
    fill=orange,
    draw=orange,
    ybar stacked,
    nodes near coords
] table [x expr=\coordindex, y index=0, meta index=0] {datatable.csv};

% The upper bound
\addplot +[
    ybar stacked,
    draw=orange!50,
    fill=orange!50,
    nodes near coords
] table [x expr=\coordindex, y index=1, meta index=1] {datatable.csv};

% The connecting line. Uses a bit of magic to typeset the ranges
\addplot [
    const plot, black,
    point meta={
        TeX code symbolic={
            \pgfkeys{/pgf/fpu/output format=fixed}
            \pgfmathtruncatemacro\upperbound{
                \thisrowno{0} + \thisrowno{1}
            }
            \edef\dostuff{
                \noexpand\def\noexpand\pgfplotspointmeta{%
                    \thisrowno{0}--\upperbound%
                }
            }%
            \dostuff
        }
    },
    nodes near coords=\pgfplotspointmeta,
    every node near coord/.style={
        font=\scriptsize,
        anchor=south
    },
] table [x expr=\coordindex, y expr=0] {datatable.csv};
\end{axis}
\end{tikzpicture}
\end{document}
Torbjørn T.
  • 206,688
P.Asea
  • 187
  • 2
    I converted your text into "code", but it appears to have been truncated at the end. Perhaps an edit is needed on your end. – Steven B. Segletes Jul 19 '17 at 11:27
  • AM really sorry. For some reason I am not able to generate code. – P.Asea Jul 19 '17 at 20:56
  • Okay now I have the complete code posted of the MWE – P.Asea Jul 19 '17 at 20:58
  • In the future (I have done this for you), after you paste your code into the edit window, highlight it and click the button above the edit box that looks like {}. It will indent everything by 4 spaces in the edit window, which has the effect of displaying it as code for the rest of us. – Steven B. Segletes Jul 19 '17 at 20:58
  • In the first plot you have an \ifnum\coordindex>2, you probably need to change that to \ifnum\coordindex>5. – Torbjørn T. Jul 19 '17 at 21:42
  • Thanks for that advice, that was helpful, but problem not solved. The final bar is "hanging" in mid air while it should show the cumulative effects intended. – P.Asea Jul 20 '17 at 13:39

1 Answers1

3

Would have been nice by the way, if you had mentioned that you got this from Waterfall Chart. There are just two things wrong, I think.

  1. The last row in your datafile should be the total sum of the above rows, so 107 177, not 61 69.

  2. In the first plot you have a \ifnum\coordindex>2 that should be changed to \ifnum\coordindex>4. \coordindex starts counting at zero, and you want the baseline to be 0 for the last bar, not the cumulative sum.

I also changed the enlarge x limits setting to enlarge x limits={abs=0.5}.

output of code

\documentclass[border=5mm]{standalone}
\usepackage{pgfplotstable}
\usepackage{filecontents}

\pgfplotsset{compat=1.5.1}

\begin{filecontents}{datatable.csv}
27  47
12  21
39  69
12 17
17 23
107 177
\end{filecontents}


\pgfplotstableset{
    create on use/accumyprev/.style={
        create col/expr={\prevrow{0}+\prevrow{1}+\pgfmathaccuma}
    }
}


% Style for centering the labels
\makeatletter
\pgfplotsset{
    centered nodes near coords/.style={
    calculate offset/.code={
        \pgfkeys{/pgf/fpu=true,/pgf/fpu/output format=fixed}
        \pgfmathsetmacro\testmacro{(\pgfplotspointmeta*10^\pgfplots@data@scale@trafo@EXPONENT@y)/2*\pgfplots@y@veclength)}
        \pgfkeys{/pgf/fpu=false}
    },
    every node near coord/.style={
        /pgfplots/calculate offset,
        yshift=-\testmacro,
        black,
        font=\scriptsize,
    },
    nodes near coords align=center
    }
}
\makeatother


\begin{document}

\begin{tikzpicture}
\begin{axis}[
width  = 0.85*\textwidth,
        height = 8cm,
    no markers,
    ybar stacked,
    bar width = 20pt,
    ymin=0,
    point meta=explicit,
    centered nodes near coords, 
    axis lines*=left,
    xtick=data,
    major tick length=0pt,
    xticklabels={
    2014\\ GDP,
        Business \\as \\ usual \\growth,
        Total \\2025 \\ business-\\as-usual \\l GDP,
        Increm-\\ental \\ best-\\in-region\\  GDP\\ in 2025,
        additional\\ GDP \\ in full\\-potential \\ scenarios in\\  2025,
        Total \\2025\\ business-\\as-usual\\ GDP,
    },
    xticklabel style={font=\small, text width=4cm, align=center},
    enlarge x limits={abs=0.5},
    ytick=\empty,
    y axis line style={opacity=0},
    ylabel style={font=\small},
    axis on top
]

% The first plot sets the "baseline": Uses the sum of all previous y values, except for the last bar, where it becomes 0
\addplot +[
    y filter/.code={\ifnum\coordindex>4 \def\pgfmathresult{0}\fi},
    draw=none,
    fill=none
] table [x expr=\coordindex, y=accumyprev] {datatable.csv};

% The lower bound
\addplot +[
    fill=orange,
    draw=orange,
    ybar stacked,
    nodes near coords
] table [x expr=\coordindex, y index=0, meta index=0] {datatable.csv};

% The upper bound
\addplot +[
    ybar stacked,
    draw=orange!50,
    fill=orange!50,
    nodes near coords
] table [x expr=\coordindex, y index=1, meta index=1] {datatable.csv};

% The connecting line. Uses a bit of magic to typeset the ranges
\addplot [
    const plot, black,
    point meta={
        TeX code symbolic={
            \pgfkeys{/pgf/fpu/output format=fixed}
            \pgfmathtruncatemacro\upperbound{
                \thisrowno{0} + \thisrowno{1}
            }
            \edef\dostuff{
                \noexpand\def\noexpand\pgfplotspointmeta{%
                    \thisrowno{0}--\upperbound%
                }
            }%
            \dostuff
        }
    },
    nodes near coords=\pgfplotspointmeta,
    every node near coord/.style={
        font=\scriptsize,
        anchor=south
    },
] table [x expr=\coordindex, y expr=0] {datatable.csv};
\end{axis}
\end{tikzpicture}
\end{document}
Torbjørn T.
  • 206,688