This happens because PGFPlots only uses one "stack" per axis: You're stacking the second confidence interval on top of the first. The easiest way to fix this is probably to use the approach described in "Is there an easy way of using line thickness as error indicator in a plot?": After plotting the first confidence interval, stack the upper bound on top again, using stack dir=minus
. That way, the stack will be reset to zero, and you can draw the second confidence interval in the same fashion as the first:
\documentclass{standalone}
\usepackage{pgfplots, tikz}
\usepackage{pgfplotstable}
\pgfplotstableread{
temps y_h y_h__inf y_h__sup y_f y_f__inf y_f__sup
1 0.237340 0.135170 0.339511 0.237653 0.135482 0.339823
2 0.561320 0.422007 0.700633 0.165871 0.026558 0.305184
3 0.694760 0.534205 0.855314 0.074856 -0.085698 0.235411
4 0.728306 0.560179 0.896432 0.003361 -0.164765 0.171487
5 0.711710 0.544944 0.878477 -0.044582 -0.211349 0.122184
6 0.671241 0.511191 0.831291 -0.073347 -0.233397 0.086703
7 0.621177 0.471219 0.771135 -0.088418 -0.238376 0.061540
8 0.569354 0.431826 0.706882 -0.094382 -0.231910 0.043146
9 0.519973 0.396571 0.643376 -0.094619 -0.218022 0.028783
10 0.475121 0.366990 0.583251 -0.091467 -0.199598 0.016664
}{\table}
\begin{document}
\begin{tikzpicture}
\begin{axis}
% y_h confidence interval
\addplot [stack plots=y, fill=none, draw=none, forget plot] table [x=temps, y=y_h__inf] {\table} \closedcycle;
\addplot [stack plots=y, fill=gray!50, opacity=0.4, draw opacity=0, area legend] table [x=temps, y expr=\thisrow{y_h__sup}-\thisrow{y_h__inf}] {\table} \closedcycle;
% subtract the upper bound so our stack is back at zero
\addplot [stack plots=y, stack dir=minus, forget plot, draw=none] table [x=temps, y=y_h__sup] {\table};
% y_f confidence interval
\addplot [stack plots=y, fill=none, draw=none, forget plot] table [x=temps, y=y_f__inf] {\table} \closedcycle;
\addplot [stack plots=y, fill=gray!50, opacity=0.4, draw opacity=0, area legend] table [x=temps, y expr=\thisrow{y_f__sup}-\thisrow{y_f__inf}] {\table} \closedcycle;
% the line plots (y_h and y_f)
\addplot [stack plots=false, very thick,smooth,blue] table [x=temps, y=y_h] {\table};
\addplot [stack plots=false, very thick,smooth,blue] table [x=temps, y=y_f] {\table};
\end{axis}
\end{tikzpicture}
\end{document}
To add legend to a place to the right of the plots, one needs to add a legend style to the groupplot
environment where at=() is the key. The (0,0) means the lower left of the corner while (1,1) means the upper right corner. Such system is called axis description cs
documented on page 103.
[legend style={at={(1.03,1.4)}, anchor=north west}
Code:
\documentclass[margin=2mm]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{groupplots}
\pgfplotsset{compat=newest}
\begin{document}
\begin{tikzpicture}[shorten >=4pt,shorten <=4pt]
\begin{groupplot}[
group style={
group size=2 by 2,
x descriptions at=edge bottom,
y descriptions at=edge left,
},
height=3.5cm,width=3.5cm,/tikz/font=\small,
xlabel=time $t$ / h,
ylabel=$c$ / mol/L,
]
\nextgroupplot% 1
\addplot coordinates {(0,1) (1,0)};
\addplot coordinates {(0,0) (1,1)};
\nextgroupplot% 2
\addplot coordinates {(0,1) (1,0)};
\addplot coordinates {(0,0) (1,1)};
\nextgroupplot% 3
\addplot coordinates {(0,1) (1,0)};
\addplot coordinates {(0,0) (1,1)};
\nextgroupplot[legend style={at={(1.03,1.4)}, anchor=north west}]% 4
\addplot coordinates {(0,1) (1,0)};
\addplot coordinates {(0,0) (1,1)};
\legend{Put the legend here};
\end{groupplot}
% \node [right=5mm,anchor=west] at
% ($(group c2r1.south east)!0.5!(group c2r2.north east)$) {}
\end{tikzpicture}
\end{document}
Update: The OP has a follow-up and this update adds more info to it. This is the principle for groupplot
. The \nextgroupplot[<axis options>]
option are the options that are supplied to the following axes until the next \nextgroupplot
command is seen by TEX. The order in which figures are typeset in a zigzag order, meaning the right-most figures are the 3rd, 6th and 9th figure. Since the OP wants legends to be vertically center, this solution uses the 9th figure as the reference point and specifies the coordinateat=(<x,y>)
. The axis description cs
remains valid. Just be aware that for outer legends x>1
and y>1
.
Code
\documentclass[margin=2mm]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{groupplots}
\pgfplotsset{compat=newest}
\begin{document}
\begin{tikzpicture}[shorten >=4pt,shorten <=4pt]
\begin{groupplot}[
group style={
group size=3 by 3,
x descriptions at=edge bottom,
y descriptions at=edge left,
},
height=3.5cm,width=3.5cm,/tikz/font=\small,
xlabel=time $t$ / h,
ylabel=$c$ / mol/L,
]
\nextgroupplot% 1
\addplot coordinates {(0,1) (1,0)};
\addplot coordinates {(0,0) (1,1)};
\nextgroupplot% 2
\addplot coordinates {(0,1) (1,0)};
\addplot coordinates {(0,0) (1,1)};
\nextgroupplot% 3
\addplot coordinates {(0,1) (1,0)};
\addplot coordinates {(0,0) (1,1)};
\nextgroupplot% 4
\addplot coordinates {(0,1) (1,0)};
\addplot coordinates {(0,0) (1,1)};
\nextgroupplot% 5
\addplot coordinates {(0,1) (1,0)};
\addplot coordinates {(0,0) (1,1)};
\nextgroupplot% 6
\addplot coordinates {(0,1) (1,0)};
\addplot coordinates {(0,0) (1,1)};
\nextgroupplot% 7
\addplot coordinates {(0,1) (1,0)};
\addplot coordinates {(0,0) (1,1)};
\nextgroupplot% 8
\addplot coordinates {(0,1) (1,0)};
\addplot coordinates {(0,0) (1,1)};
\nextgroupplot[legend style={at={(1.1,2.2)}, anchor=north west}]% 9
\addplot coordinates {(0,1) (1,0)};
\addplot coordinates {(0,0) (1,1)};
\legend{Put the legend here};
\end{groupplot}
% \node [right=5mm,anchor=west] at
% ($(group c2r1.south east)!0.5!(group c2r2.north east)$) {}
\end{tikzpicture}
\end{document}
Best Answer
In order to colour each bar differently and make it appear with its own legend entry, each bar needs to be handled as its own plot, i.e. it needs its own
\addplot ...
command. Fortunately, you don't have to write\addplot ...
seven times, but instead you can use\pgfplotsinvokeforeach {0,...,6} { \addplot ... }
.I would suggest you provide the data in a table, either in an external datafile or in a macro created using
\pgfplotstableread
. This makes it easier to loop over the data, and it makes your data more maintainable (thecoordinate
syntax becomes quite tedious for larger datasets).To provide different colours for the bars, you can define a new
cycle list
using\pgfplotscreatecyclelist
. In the example below, I've defined seven colours according to a Colorbrewer color scheme and used them to define a new cycle list.To create one legend for all of the plots, you can use the key
legend to name=<name>
, which stores the legend in a\label
, so you can create it somewhere else using\ref{<name>}
. In this case, I put it below the center of the second axis, so it aligns nicely with the axes. If it was centered according to the page, it would look misaligned.By default, the entries in horizontal legends are quite close together. I've inserted a bit more space using the approach described in How can I adjust the horizontal spacing between legend entries in PGFPlots?.
To make the whole plot take up a specified width, you have to do a few calculations, as described in the accepted answer to pgfplots: how can I scale to text width?. You have to specify the plot width with the key
scale only axis
activated, the space taken up by the y tick labels and the y axis label, and the space between the groupplots, and these dimensions have to add up to your desired overall width. In this case, I set the space between the plots to0.05\textwidth
(so0.1\texwidth
in total, because there are three plots), the space for the leftmost ytick labels to0.035\textwidth
with an offset of0.005\textwidth
, so0.04\textwidth
overall, the space for the y label to0.02\textwidth
, and the width of the axes to0.74\textwidth/3
. This adds up to0.74\textwidth/3 * 3 + 0.02\textwidth + 0.04\textwidth + 0.1\textwidth = 0.9\textwidth
. Try setting the axis width to0.84\textwidth/3
: This will make the whole environment exactly\texwidth
wide.