1

I have a stacked bar chart that looks like this.enter image description here

However, I'm trying to include the negative values (ninth column in the datatable) into the total value on the stacked bar chart so that in the end some of the total values are negative like this:

enter image description here.

Here's my MWE:

\documentclass[a4paper]{report}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{dateplot}
\pgfplotsset{compat=newest}
\pgfplotsset{
        show sum on top/.style={
            /pgfplots/scatter/@post marker code/.append code={%
                \node[
                    at={(normalized axis cs:%
                            \pgfkeysvalueof{/data point/x},%
                            \pgfkeysvalueof{/data point/y})%
                    },
                    anchor=south,
                ]
                {\pgfmathprintnumber{\pgfkeysvalueof{/data point/y}}};
            },
        },
    }
\begin{document}
 \pgfplotstableread{
Year    OneCol  SecCol  ThirdCol ForthCol FifthCol SixthCol SeventhCol EigthCol NinthCol TenthCol EleventhCol
2005    0.2 0.0 0.0 0.0 0.0 0.1 0.0 0.0 -2.5    0.0 0.3  
2006    0.3 0.0 0.0 0.0 0.0 0.1 0.0 0.0 -2.5    0.0 0.3
2007    0.5 0.0 0.0 0.0 0.0 0.2 0.0 0.0 -2.1    0.0 0.8
2008    1.2 0.0 0.0 0.0 0.0 0.6 0.0 0.0 -1.8    0.0 1.9
2009    0.5 0.0 0.0 0.0 0.0 0.3 0.0 0.0 -2.1    0.0 0.9
2010    3.9 0.0 0.0 0.0 0.0 1.0 0.0 0.0 -1.4    0.0 5.6
2011    0.6 0.0 0.0 0.0 0.0 0.3 0.0 0.0 -1.9    -0.1 0.8
2012    11.1 0.0 0.0 0.0 0.0 2.0 0.0 0.0 -1.0   0.0 13.7
2013    0.2 0.0 0.0 0.0 0.0 0.1 0.0 0.0 -2.6    0.0 0.2
}\datatable

\begin{figure}
\centering
 \begin{tikzpicture}
    \begin{axis}[
      width=0.9*\textwidth,
      bar width=0.26cm,
      tick label style={/pgf/number format/1000 sep=,font=\footnotesize},
      stack negative=on previous,
      ybar stacked,
      bar width=1em,
      ymin=-10,
      axis on top,
      ymax=30,
      ymajorgrids = true,
      enlarge x limits={true, abs value=0.75},
      height=8cm,
      nodes near coords={},
      legend style={
      at={(1.1,0.5)},
      anchor=west,
      draw=none },
      xtick=data,
      xticklabels={GWP,ODP,POCP, AP, EP(T), EP(FW), EP(M), ADP, CED}
      ]
      \addplot [fill=cyan!70,draw=black!70] table [y index=1] {\datatable};
      \addplot [fill=green!90,draw=black!70] table [y index=2] {\datatable};
      \addplot [fill=teal!90,draw=black!70]table [y index=3] {\datatable};
      \addplot [fill=violet!90,draw=black!70]table [y index=4] {\datatable};
      \addplot [fill=lime!90,draw=black!70]table [y index=5] {\datatable};
      \addplot [fill=magenta!90,draw=black!70]table [y index=6] {\datatable};
      \addplot [fill=red!90,draw=black!70]table [y index=7] {\datatable};
      \addplot [fill=blue!90,draw=black!70]table [y index=8] {\datatable};
      \addplot [fill=yellow!90,draw=black!70] table [y index=9] {\datatable};
      \addplot [fill=purple!90,draw=black!70] table [y index=10] {\datatable};
      \addplot [fill=olive!90,draw=black!70,show sum on top] table [y index=11] {\datatable};
  \legend{Facade,Column,Core,Drywall,Foundation,Roof,Slab,Window,Operation,Disposal,Replacement}
    \end{axis}
  \end{tikzpicture}
  \caption{Impacts by category relative to baseline building with conventional building envelope}
\label{relative}
  \end{figure}
\end{document}

Appreciate your help, thanks!

  • Hey thanks for answering. I want the total value on top of each bar to include the negative values because obviously the negative values in the ninth column are ignored in the sum of every bar. (You can see the total values in the two pictures are different - due to the exclusion of negative values in the first pic) – thesilencer Dec 12 '18 at 13:08
  • Thanks for the clarification! May I ask you to append this to your question? Then others having similar issues can more easily understand what's going on here. – user121799 Dec 12 '18 at 13:28
1

The main issue is that your keys are not ordered appropriately. You need to move stack negative=on previous after ybar stacked. And I also took the liberty to make the anchors depend on the sign of the coordinates such that they will be below the bars (rather than interfere) for negative y values.

\documentclass[a4paper]{report}
\usepackage{pgfplots}
\usetikzlibrary{calc}
\usepackage{pgfplotstable}
\usepgfplotslibrary{dateplot}
\pgfplotsset{compat=newest}
\pgfplotsset{
        show sum on top/.style={
            /pgfplots/scatter/@post marker code/.append code={%
                \path let \p1=($(normalized axis cs:%
                            \pgfkeysvalueof{/data point/x},%
                            \pgfkeysvalueof{/data point/y})%
                            -(normalized axis cs:\pgfkeysvalueof{/data point/x},0)$)
                in node[
                    at={(normalized axis cs:%
                            \pgfkeysvalueof{/data point/x},%
                            \pgfkeysvalueof{/data point/y})%
                    },
                    anchor={-90*sign(\y1)},yshift={sign(\y1)*2pt}
                ]
                {\pgfmathprintnumber{\pgfkeysvalueof{/data point/y}}};
            },
        },
    }
\begin{document}
 \pgfplotstableread{
Year    OneCol  SecCol  ThirdCol ForthCol FifthCol SixthCol SeventhCol EigthCol NinthCol TenthCol EleventhCol
2005    0.2 0.0 0.0 0.0 0.0 0.1 0.0 0.0 -2.5    0.0 0.3  
2006    0.3 0.0 0.0 0.0 0.0 0.1 0.0 0.0 -2.5    0.0 0.3
2007    0.5 0.0 0.0 0.0 0.0 0.2 0.0 0.0 -2.1    0.0 0.8
2008    1.2 0.0 0.0 0.0 0.0 0.6 0.0 0.0 -1.8    0.0 1.9
2009    0.5 0.0 0.0 0.0 0.0 0.3 0.0 0.0 -2.1    0.0 0.9
2010    3.9 0.0 0.0 0.0 0.0 1.0 0.0 0.0 -1.4    0.0 5.6
2011    0.6 0.0 0.0 0.0 0.0 0.3 0.0 0.0 -1.9    -0.1 0.8
2012    11.1 0.0 0.0 0.0 0.0 2.0 0.0 0.0 -1.0   0.0 13.7
2013    0.2 0.0 0.0 0.0 0.0 0.1 0.0 0.0 -2.6    0.0 0.2
}\datatable

\begin{figure}
\centering
 \begin{tikzpicture}
    \begin{axis}[
      width=0.9*\textwidth,
      bar width=0.26cm,
      tick label style={/pgf/number format/1000 sep=,font=\footnotesize},
      ybar stacked,
      stack negative=on previous, %<- moved down
      bar width=1em,
      ymin=-10,
      axis on top,
      ymax=30,
      ymajorgrids = true,
      enlarge x limits={true, abs value=0.75},
      height=8cm,
      nodes near coords={},
      legend style={
      at={(1.1,0.5)},
      anchor=west,
      draw=none },
      xtick=data,
      xticklabels={GWP,ODP,POCP, AP, EP(T), EP(FW), EP(M), ADP, CED}
      ]
      \addplot [fill=cyan!70,draw=black!70] table [y index=1] {\datatable};
      \addplot [fill=green!90,draw=black!70] table [y index=2] {\datatable};
      \addplot [fill=teal!90,draw=black!70]table [y index=3] {\datatable};
      \addplot [fill=violet!90,draw=black!70]table [y index=4] {\datatable};
      \addplot [fill=lime!90,draw=black!70]table [y index=5] {\datatable};
      \addplot [fill=magenta!90,draw=black!70]table [y index=6] {\datatable};
      \addplot [fill=red!90,draw=black!70]table [y index=7] {\datatable};
      \addplot [fill=blue!90,draw=black!70]table [y index=8] {\datatable};
      \addplot [fill=yellow!90,draw=black!70] table [y index=9] {\datatable};
      \addplot [fill=purple!90,draw=black!70] table [y index=10] {\datatable};
      \addplot [fill=olive!90,draw=black!70,show sum on top] table [y index=11] {\datatable};
  \legend{Facade,Column,Core,Drywall,Foundation,Roof,Slab,Window,Operation,Disposal,Replacement}
    \end{axis}
  \end{tikzpicture}
  \caption{Impacts by category relative to baseline building with conventional building envelope}
\label{relative}
  \end{figure}
\end{document}

enter image description here

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.