# Fill area of curve above a line using pgfplots

This question is related to Fill between two curves in pgfplots. which started me of.

However, I need to have just the area above the reference line filled.

\begin{tikzpicture}

\pgfplotstablesort[sort cmp={float >}]\coordinates{
0 0.9
33 0.9}

\pgfplotstablevertcat{\filledcurve}{\coordinates}
\pgfplotstablevertcat{\filledcurve}{\data}
\pgfplotstabletypeset{\filledcurve}

\begin{axis}[xlabel=Time of day, ylabel=Volume,xtick=\empty,ytick=\empty, axis x line=bottom, axis y line=left,enlargelimits=true]
\end{axis}
\end{tikzpicture}


The datafile looks like:

0 0.2
1 0.217
2 0.255
3 0.288
6 0.58
7 0.9
8 1.02


In the code above I would like that just the area of \data above \coordinates is filled grey. Does anyone got a hint?

-
Welcome to Tex.SX. Please provide a full MWE including \documentclass. You could try to use the solution you liked to and fill the area between the curve and the line y=<y axis max> and use draw=none for that line so it does not get drawn. –  Peter Grill Aug 15 '11 at 20:13

Here's a macro that generates a new table \interpolated that places points on your original data at every intersection with a certain y-value. You call it using \findintersections{<table macro}{<value>}.

To plot the area above the line, you would then use \addplot[fill,gray!20!white,no markers,line width=2pt] table [y=above line] {\interpolated};, or ...table [y=below line] for the area below the line.

In order to close the area properly in case your plot stops or begins above the cutoff line, you should add |- (current plot begin) at the end of the plot command.

\documentclass{article}

\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepackage{filecontents}
\usetikzlibrary{calc}
\begin{filecontents}{data.dat}
0 0.2
1 0.217
2 0.255
3 0.288
6 0.58
7 0.91
8 1.02
10 1.05
12 0.92
13 0.78
15 0.56
17 1.1
\end{filecontents}

\newcommand\findintersections[2]{
\def\prevcell{#1}
\pgfplotstableforeachcolumnelement{1}\of#2\as\cell{%
\pgfmathparse{!or(
and(
\prevcell>#1,\cell>#1
),
and(
\prevcell<#1,\cell<#1
)
)}

\ifnum\pgfmathresult=1
\pgfplotstablegetelem{\pgfplotstablerow}{0}\of{\data} \let\xb=\pgfplotsretval
\pgfplotstablegetelem{\pgfplotstablerow}{1}\of{\data} \let\yb=\pgfplotsretval
\pgfmathtruncatemacro\previousrow{ifthenelse(\pgfplotstablerow>0,\pgfplotstablerow-1,0)}
\pgfplotstablegetelem{\previousrow}{0}\of{\data} \let\xa=\pgfplotsretval
\pgfplotstablegetelem{\previousrow}{1}\of{\data} \let\ya=\pgfplotsretval
\pgfmathsetmacro\newx{
\xa+(\ya-#1)/(ifthenelse(\yb==\ya,1,\ya-\yb) )*(\xb-\xa)    }

0,1\noexpand\\
\newx,#1\noexpand\\
}\noexpand\newrow}
\test
\pgfplotstablevertcat\interpolated{\newrow}
\fi
\let\prevcell=\cell
}
\pgfplotstablevertcat\interpolated{#2}
\pgfplotstablesort[sort cmp={float <}]\interpolated{\interpolated}
\pgfplotstableset{
create on use/above line/.style={
create col/expr={max(\thisrow{1},#1)}
},
create on use/below line/.style={
create col/expr={min(\thisrow{1},#1)}
},
}
}

\begin{document}
\pgfplotsset{compat=newest} % For nicer label placement

\findintersections{0.9}{\data}

\begin{tikzpicture}
\begin{axis}[
xlabel=Time of day,
ylabel=Volume,
ytick=\empty,
axis x line=bottom,
axis y line=left,
enlargelimits=true
]
\addplot[fill,gray!20!white,no markers,line width=2pt] table [y=above line] {\interpolated} |- (current plot begin);
\addplot[fill,yellow!20!white,no markers,line width=2pt] table [y=below line] {\interpolated} |- (current plot begin);
\end{axis}
\end{tikzpicture}

\end{document}

-
Thanks a lot! That exactly works as I needed! –  ThijsMuis Aug 16 '11 at 6:31
This works great, unless there is a file named data.dat.tex in the same directory. Took my quite some time to figure this out so thought I'd put that info here in case others encounter problems with this. –  Peter Grill Aug 16 '11 at 16:06
Note though that this happens because I used the filecontents environment in my example to keep everything in one file. In a real application, the filecontents package and environment would not be used. –  Jake Aug 16 '11 at 22:42

With the recently released pgfplots 1.10 and its fillbetween library (I learned it from Elke here) it's much easier.

• Load the library: \usepgfplotslibrary{fillbetween}
• Give the plots a name: \addplot[name path=curve,orange, ...

  \addplot fill between[
of = curve and line,
split, % calculate segments
every even segment/.style = {yellow!20!white},
every odd segment/.style ={gray!20!white}
];


Complete example:

\documentclass{article}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{fillbetween}
\usetikzlibrary{calc}
\usepackage{filecontents}
\begin{filecontents}{data.dat}
0 0.2
1 0.217
2 0.255
3 0.288
6 0.58
7 0.91
8 1.02
10 1.05
12 0.92
13 0.78
15 0.56
17 1.1
\end{filecontents}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
xlabel=Time of day,
ylabel=Volume,
ytick=\empty,
axis x line=bottom,
axis y line=left,
enlargelimits=true
]