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}
You can define a customized math "function" which relies on the fact that it is evaluated while the input table is read. In other words, it is only valid within your context.
It uses the FPU of pgf which is used by pgfplots, and, in particular, its method \pgfmathfloatparsenumber
. A float in pgf has "flags" which is an integer with the meaning
0 == '0' (the number is +- 0.0),
1 == '+',
2 == '-',
3 == 'not a number'
4 == '+ infinity'
5 == '- infinity'
consequently, we can call \pgfmathfloatparsenumber
and use \pgfmathfloatgetflagstomacro
to access the flag. Integer comparisons can be done by means of \ifnum<int>=<int> \else \fi
.
Defining two functions, one for Y and one for the error bar results in
\documentclass[11pt]{article}
\usepackage{pgfplots}
\usepackage{filecontents}
\usepackage{verbatim}
\begin{filecontents*}{data.dat}
time w1 e1 w2 e2
1 3019 40 nan nan
2 3045 34 nan nan
3 3100 50 3104 24
4 3500 13 3498 90
5 3800 90 3803 12
6 nan nan 3980 43
7 nan nan 3985 80
\end{filecontents*}
\begin{document}
\thispagestyle{empty}
% if (index 1 and index 3 are not NaN):
% y expr= (index 1 + index 3)/2
% y error expr= max{index 2, index 4}
% else if (index 3 = NaN): % && index 1 is not NaN
% y index =1
% y error index=2
% else if (index 1 = NaN): % && index 3 is not NaN
% y index =3
% y error index=4
\pgfmathdeclarefunction{VAL}{0}{%
\pgfmathfloatparsenumber{\thisrowno{1}}\let\A=\pgfmathresult
\pgfmathfloatparsenumber{\thisrowno{3}}\let\C=\pgfmathresult
\pgfmathfloatgetflagstomacro\A\flags
\ifnum\flags=3 %
\pgfmathfloatgetflagstomacro\C\flags
\ifnum\flags=3 %
% A == nan && C == nan
\let\pgfmathresult=\A
\else
% A == nan && C != nan
\let\pgfmathresult=\C
\fi
\else
\pgfmathfloatgetflagstomacro\C\flags
\ifnum\flags=3 %
% A != nan && C == nan
\let\pgfmathresult=\A
\else
% A != nan && C != nan
\pgfmathparse{(\A + \C)/2}%
\fi
\fi
}%
\pgfmathdeclarefunction{VALERR}{0}{%
\pgfmathfloatparsenumber{\thisrowno{1}}\let\A=\pgfmathresult
\pgfmathfloatparsenumber{\thisrowno{2}}\let\B=\pgfmathresult
\pgfmathfloatparsenumber{\thisrowno{3}}\let\C=\pgfmathresult
\pgfmathfloatparsenumber{\thisrowno{4}}\let\D=\pgfmathresult
\pgfmathfloatgetflagstomacro\A\flags
\ifnum\flags=3 %
\pgfmathfloatgetflagstomacro\C\flags
\ifnum\flags=3 %
% A == nan && C == nan
\let\pgfmathresult=\B
\else
% A == nan && C != nan
\let\pgfmathresult=\D
\fi
\else
\pgfmathfloatgetflagstomacro\C\flags
\ifnum\flags=3 %
% A != nan && C == nan
\let\pgfmathresult=\B
\else
% A != nan && C != nan
\pgfmathparse{max(\B,\D)}%
\fi
\fi
}%
\begin{tikzpicture}
\begin{axis} [
compat=newest,
y tick label style={/pgf/number format/1000 sep=},
ymin=2900,
ymax=4400]
\addplot [color=blue, thick,
error bars/.cd,
y explicit,
y dir=both,
] table [
x index=0,
y expr=VAL,
y error expr=VALERR,
]
{data.dat};
\addlegendentry{fit}
\end{axis}
\end{tikzpicture}
\end{document}
note that I have eliminated the two other \addplot
statements.
The \let\<macro>=<othermacro>
copies <othermacro>
to <macro>
. The constructions \ifnum<\macro>=3 %
compares two integers. Note the trailing space after 3
, it is important to tell TeX that it should stop to search for further numeric literals. It will be omitted from the output.
Best Answer
If I understand correctly what do you mean by "shift", you can use the
x expr
andy expr
options like this: