# ybar stacked plot with negative coordinates

When using ybar stacked on a mix of positive and negative coordinates I cannot seem to find the answer I want.

\begin{figure}
\begin{tikzpicture}
\begin{axis}[ybar stacked]
\addplot[green,fill=green] coordinates { (1, 3) (2, 3) (3,3) (4,3) };
\addplot[red,fill=red]     coordinates { (1,-4) (2,-4) (3,4) (4,4) };
\end{axis}
\end{tikzpicture}
\end{figure}


I'd like to get all red bars 4 units long (as they are in the coordinates), though the left two bars are hiding behind the green ones. Is there any solution to this? (Changing the order of the \addplot calls in the code above cannot fix it.)

-
Welcome to TeX.SE. I am not sure I understand exactly what you want. Are you sure you want to use ybar stacked? Perhaps what you are looking for is just ybar? – Peter Grill Apr 30 '12 at 17:38
I got a number of data vectors that all make up a summed vector. When drawing these data vectors as ybar stacked, one can nicely see their individual contributions. If all data are positive, this is fine. If some of them are negative, though, the results in the bar heights become false (because the actual bar seems to be drawn from the top coordinates of the previous bar). It would be right, I think, when positive coordinates (values) of actual bars are drawn on top of positively oriented bar stacks, and negative coordinates on top of bars (or zero-axis) in negative y-axis direction. – Jörg Peter Apr 30 '12 at 18:01
I think the definition of stacked is that the "bar is drawn from the top coordinates of the previous bar". Since you have negative coordinates, the bar is drawn downward from the top of the previous bar exactly, and hence the overlap. Still not sure I understand what you want. Perhaps if you posted an image of the desired solution it would be clearer (even if you have to manually tweak the coordinates, to be able to show the desired result). – Peter Grill Apr 30 '12 at 18:09

I would suggest to use the ybar stacked plot style, but with the components horizontally offset, which constitutes a "waterfall chart". This works nicely to show how positive and negative contributions add up to the final value (better than drawing the negative components below the y axis, which would misleadingly create a greater total length).

For drawing the connectors between the bars, you'll have to define a new marker using \pgfdeclareplotmark.

\documentclass{article}
\usepackage{pgfplots}

\pgfdeclareplotmark{waterfall bridge}{\pgfpathmoveto{\pgfpoint{-13pt}{0pt}}\pgfpathlineto{\pgfpoint{13pt}{0pt}}\pgfusepathqstroke}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
ybar stacked,
bar width=10pt,
axis lines*=middle,
axis on top=false,
xtick=data,
enlarge y limits=0.2,
after end axis/.code={
\node at ({rel axis cs:0,0}|-{axis cs:0,0}) [anchor=east] {0};
}
]
fill=cyan,
draw=none,
bar shift=-8pt,
mark options={
gray,
thick,
dashed
},
mark=waterfall bridge
] coordinates { (1, 3) (2, 3) (3,3) (4,3) };
fill=orange,
draw=none,
bar shift=8pt
] coordinates { (1,-4) (2,-4) (3,4) (4,4) };
\end{axis}
\end{tikzpicture}

\end{document}

-
Sorry to resurrect an old thread. Is there any way to give each waterfall segment a label on the x axis? For instance in your example the blue bars would be 1a, 2a, etc, and the orange bars would be 1b, 2b, etc. – Trevor Mar 1 '13 at 21:25

I've run into this problem many times as well. My (admittedly ugly) workaround is to create the negative bars in a separate axis environment. It's suboptimal because you have to make sure the dimensions and bar widths are the same for both axes, and you have to get rid of axis lines on the second axis, but it does achieve the desired effect.

-

The solution we have come up with is relatively non-intrusive. Your latex code stays the same, no additional special tags, but your x co-ordinates of your negative values changes a little bit.

Since every x co-ordinate by default is stacked separately, we would plot the positives at e.g. 1, 2, 3, etc and the negatives at 0.999, 1.999, 2.999, etc.

For the human eye, it would appear to be directly on top of each other (if not, add another 9), but for purposes of stacking, latex will stack them separately.

here is a code extract of the .tex tile:

. . .
\begin{axis}[width=20cm, height=9.75cm,
scaled ticks=false,%
%bar width=5pt,
xmin=-0.15,
xtick={1,...,\days},
xmax=\the\value{daysp}.15,
ylabel=energy in \si{kWh},
xlabel = date,
%xlabel= {\yearnow},
%xtick align=center,
%xticklabel style={rotate=90,anchor=east},
grid=major,
legend cell align=left,
%legend entries={baseline,target,trend,low demand--off-peak,low demand--standard,low demand--peak,high demand--off-peak,high demand--standard,high demand--peak},
legend style = {area legend,legend columns = 4,
%legend title = legend,
at={(0.5,-0.12)},
anchor=north},
%legend entries={baseline,target,trend,low demand--off-peak,low demand--standard,low demand--peak,high demand--off-peak,high demand--standard,high demand--peak},
title={{\month} {\yearnow} consumption for \meter},
%title style={at={(0.5,1)}},
ybar stacked,
set layers
]
. . .
\trend ;
\addplot[draw=black, fill=color8, forget plot] table [x=x,y=v8]{Month.csv};
\addplot[draw=black, fill=color1, forget plot] table [x=x,y=v1]{Month.csv};
\addplot[draw=black, fill=color12, forget plot] table [x=x,y=v12]{Month.csv};
\addplot[draw=black, fill=color6, forget plot] table [x=x,y=v6]{Month.csv};
\addplot[draw=black, fill=color9, forget plot] table [x=x,y=v9]{Month.csv};
\addplot[draw=black, fill=color3, forget plot] table [x=x,y=v3]{Month.csv};
. . .


and an extract from a similar Month.csv file (not exactly the same as the picture, but it shows the idea) (columns are tab delimited):

x   v7  v8  v1  v2  v11 v12 v5  v6  v9  v10 v3  v4  target
. . .
6.25    0   0   0   0   0   0   0   0   0   0   0   0   1682.16
6.5 0   0   0   0   0   0   0   0   0   0   0   0   1682.16
6.999   0   0   -30 0   0   0   0   0   0   0   -54.500 0   1682.16
7   0   0   0   200 0   0   0   0   0   0   0   1190.000    1682.16
7.25    0   0   0   0   0   0   0   0   0   0   0   0   1682.16
7.5 0   0   0   0   0   0   0   0   0   0   0   0   1682.16
7.999   0   0   -50 0   0   0   0   0   0   0   -93.000 0   1682.16
8   0   0   0   400 0   0   0   0   0   0   0   1068.000    1682.16
. . .

-
Could you also provide the code for the solution? This would help a lot future readers. – Claudio Fiandrino Nov 18 at 8:10