# Fill the area enclosed by multiple functions in a single plot

I wish to fill the area enclosed by four functions, as indicated by the hatching in red in the figure below:

So far I've been able to fill the area between each pair of functions, as shown below:

The first was produced as follows:

\documentclass{standalone}
\usepackage{pgfplots}
\begin{document}

\pgfmathdeclarefunction{fun1}{0}{%
\pgfmathparse{ tan(x)/( cos(x)*( 1 + 3.3*((tan(x))^2) ) ) }}
\pgfmathdeclarefunction{fun2}{0}{%
\pgfmathparse{ 1.1*tan(x)*(1/cos(x)) }}
\pgfmathdeclarefunction{fun3}{0}{%
\pgfmathparse{ 0.145*( ( 1 + 3.3*(tan(x))^2 ) / sin(x) ) }}
\pgfmathdeclarefunction{fun4}{0}{%
\pgfmathparse{ 4 }}

\begin{tikzpicture}
%
\begin{semilogyaxis}[%
width=7cm,height=11cm,
scale only axis,
xmin=0, xmax=90,
xmajorgrids,
ymin=0.1, ymax=10,
ymajorgrids,yminorgrids]

% fun1 (start stacking)
domain=1:25.70,
draw=none,fill=none,mark=none,
stack plots=y]
{ fun1 };
%
% stack difference between fun2 and fun1 on top of fun1
domain=1:25.70,
draw=none,draw opacity=0.0,
fill=gray,fill opacity=0.25,
stack plots=y
]
{ max( fun2 - fun1 , 0 ) }
\closedcycle;

% fun1
\addplot[domain=1:89,solid,line width=0.8pt,draw=black,mark=none]{ fun1 };

% fun2 (branch 1)
\addplot[domain=1:25.78,solid,line width=0.8pt,draw=black,mark=none]{ fun2 };
% fun2 (branch 2)

% fun3 (branch 1)
% fun3 (branch 2)
\addplot[domain=25.78:70,solid,line width=0.8pt,draw=black,mark=none]{ fun3 };
% fun3 (branch 3)

% fun4 (branch 1)
% fun4 (branch 2)
\addplot[domain=70:89,solid,line width=0.8pt,draw=black,mark=none]{ fun4 };

\end{semilogyaxis}
\end{tikzpicture}
\end{document}


The 2nd and 3rd were obtained, respectively, using:

• domain=25.78:70 and { max( fun3 - fun1 , 0 ) }
• domain=70:89 and { max( fun4 - fun1 , 0 ) }

How can I display them on a single plot?

-
If what you want is combining three plots into one tikzpicture, I don't see how the current title (Fill the area enclosed by multiple functions) is descriptive of the problem at all... –  Jubobs May 6 '13 at 9:23
@Jubobs feel free to edit the title, or otherwise suggest a more appropriate one. –  nnunes May 6 '13 at 9:38
@nnunnes Oops. Sorry; I had completely misunderstood your question. I'll scrap my answer. Your lastest edit helps a lot in clarifying the question, I think. –  Jubobs May 6 '13 at 9:40

You can define a new piecewise function fun5(x) combining fun2, fun3 and fun4 and fill the area between fun1 and fun5:

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\begin{document}

\pgfmathdeclarefunction{fun1}{1}{%
\pgfmathparse{tan(#1)/(cos(#1)*(1+3.3*((tan(#1))^2)))}}
\pgfmathdeclarefunction{fun2}{1}{%
\pgfmathparse{1.1*tan(#1)*(1/cos(#1))}}
\pgfmathdeclarefunction{fun3}{1}{%
\pgfmathparse{0.145*((1+3.3*(tan(#1))^2)/sin(#1))}}
\pgfmathdeclarefunction{fun4}{1}{%
\pgfmathparse{4}}
\pgfmathdeclarefunction{fun5}{1}{%
\pgfmathparse{%
(#1>=1 && #1<=25.78)*fun2(#1) +%
(#1>25.78 && #1<=70)*fun3(#1) +%
(#1>70 && #1<89)*fun4(#1)}}

\begin{tikzpicture}
%
\begin{semilogyaxis}[%
width=7cm,height=11cm,
scale only axis,
xmin=0, xmax=90,
xmajorgrids,
ymin=0.1, ymax=10,
ymajorgrids,yminorgrids]
% area
{fun1(x)};
%
\addplot [domain=1:89,draw=none,fill=gray,fill opacity=0.25,stack plots=y]
{max(fun5(x) - fun1(x),0)}
\closedcycle;
%
% fun1
\addplot [domain=1:89,line width=0.8pt] {fun1(x)};
% fun2 (branch 1)
% fun2 (branch 2)
%
% fun3 (branch 1)
% fun3 (branch 2)
% fun3 (branch 3)
%
% fun4 (branch 1)
% fun4 (branch 2)
\end{semilogyaxis}
\end{tikzpicture}
\end{document}


-

Version 1.10 of pgfplots has been released just recently, and it comes with a new solution for the problem to fill the area between plots.

Note that the old solution is still possible and still valid; this here is merely an update which might simplify the task. In order to keep the knowledge base of this site up-to-date, I present a solution based on the new fillbetween library here:

\documentclass{standalone}
\usepackage{pgfplots}

\pgfplotsset{compat=1.10}
\usepgfplotslibrary{fillbetween}

\begin{document}

\pgfmathdeclarefunction{fun1}{0}{%
\pgfmathparse{ tan(x)/( cos(x)*( 1 + 3.3*((tan(x))^2) ) ) }}
\pgfmathdeclarefunction{fun2}{0}{%
\pgfmathparse{ 1.1*tan(x)*(1/cos(x)) }}
\pgfmathdeclarefunction{fun3}{0}{%
\pgfmathparse{ 0.145*( ( 1 + 3.3*(tan(x))^2 ) / sin(x) ) }}
\pgfmathdeclarefunction{fun4}{0}{%
\pgfmathparse{ 4 }}

\begin{tikzpicture}
%
\begin{semilogyaxis}[%
width=7cm,height=11cm,
scale only axis,
xmin=0, xmax=90,
xmajorgrids,
ymin=0.1, ymax=10,
ymajorgrids,yminorgrids]

% fun1
\addplot[name path=fun1,domain=1:89,red]{ fun1 };

% fun2
\addplot[name path=fun2,domain=1:78.89,blue]{ fun2 };

% fun3
\addplot[name path=fun3,domain=1:89,brown,]{ fun3 };

% fun4
\addplot[name path=fun4,domain=1:89,orange]{ fun4 };

\path[name path=intermediate,
%draw, line width=2pt,
intersection segments={of=fun2 and fun3,
sequence=A0 -- B1,
},
];
\path[name path=segments,
%draw, line width=2pt,
intersection segments={of=intermediate and fun4,
sequence=A0 -- B1,
},
];

\addplot[gray,fill opacity=0.25] fill between[of=segments and fun1];
\end{semilogyaxis}
\end{tikzpicture}

\end{document}


This solution just has the four functions without any modifications. However, it assigns a label to each of them. Then, we have to \path instructions which compute intersection segments: the first \path instruction generates an intermediate path which will be discarded. Note that \path without draw or fill has no visible output (and generates only scopes in the resulting pdf, no path instructions). The first intermediate path consists of the intersection segments of fun2 and fun3, namely the segments A0 which means "first (0th) segment of the first argument (fun2)". Graphically, this is the lower left edge of the filled region (blue and brown). The first argument is always called A in this context, segment indices start at 0. This segment is connected with B1 which means the second (1st) segment of the second argument in of=fun2 and fun3 (i.e. the second segment of fun3).

The second \path instruction computes intersection segments of intermediate and fun4. Keep in mind that fun4 is the top path (the orange one). Here, we take A0 (the first intersection segment of intermediate) and connect it with B1 (the second = 1st segment of fun4).

Both of these \path instructions result in no visible output (unless you insert the uncomment draw keys). They only store the results under a name.

Finally, the last \addplot fill between statement fills the area between our computed segments and fun1. To this end, it uses the fill options gray,fill opacity=0.25.

-