43

This is essentially the same question as fill the area between two curves when their coordinates are known.

In that question, the curves were defined by known coordinates. I want to fill the area between two curves but I want the curves to be calculated from pgfplots (or gnuplot).

Let's say that the curves are defined by these functions:

f(x) = sqrt(x)

g(x) = sqrt(x/2)

4 Answers 4

46

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:

enter image description here

\documentclass{standalone}
\usepackage{tikz,pgfplots}

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

\begin{document} 
\begin{tikzpicture}
    \begin{axis}[thick,smooth,no markers]
        \addplot+[name path=A,black] {sqrt(x)};
        \addplot+[name path=B,black] {sqrt(x/2)};

        \addplot[blue!50] fill between[of=A and B];
    \end{axis}
\end{tikzpicture}
\end{document}

The solution relies on \usepgfplotslibrary{fillbetween} which activates the syntax \addplot fill between[of=<first> and <second>]. The style for the filled region is given in the option list as usual, it is blue!50. Note that the fill between segment will automatically be drawn on a separate layer, i.e. it is behind the main paths.

0
16

You can (ab)use stack plots. Simply subtract the first function from the second to undo the stacking.

\documentclass{article}
\usepackage{tikz,pgfplots}

\begin{document} 
\begin{tikzpicture}
    \begin{axis}[stack plots=y,thick,smooth,no markers]
        \addplot+[black]              gnuplot{sin(x)};
        \addplot+[black,fill=blue!50] gnuplot{cos(x)-sin(x)} 
          \closedcycle;
    \end{axis}
\end{tikzpicture}
\end{document}

result

To get a better looking result, you should probably draw the filling and the curves separately:

\begin{axis}[stack plots=y,thick,smooth,no markers]
    \addplot+[black]                  gnuplot{sin(x)};         % sin
    \addplot+[black]                  gnuplot{cos(x)-sin(x)};  % cos
    \addplot[fill=blue!50,draw=none]  gnuplot{sin(x)-cos(x)}   % fill to sin
       \closedcycle;
\end{axis}
1
  • 1
    Is there any way to label the filled regions? or draw arrows or something to them?
    – Jeel Shah
    Jan 23, 2014 at 19:39
12

Result:

enter image description here

Code below. I'm assuming you're ok with defining the horizontal axis as an evenly-spaced set of points across an interval. I'm using pgfplotstable to define table elements in terms of mathematical expressions, and then using those tables to define paths like you saw in the linked question.

\documentclass{article}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\begin{document}

% Make two tables for the data -- use the same column names for each
\pgfplotstablenew[
  create on use/x/.style={create col/expr={.5+\pgfplotstablerow*0.05}},
  create on use/y/.style={create col/expr={sqrt(\thisrow{x}}},
  columns={x,y}]
  {21}
  \ftable
%\pgfplotstabletypeset\ftable
\pgfplotstablenew[
  create on use/x/.style={create col/expr={.5+\pgfplotstablerow*0.05}},
  create on use/y/.style={create col/expr={sqrt(\thisrow{x}/2)}},
  columns={x,y}]
  {21}
  \gtable
%\pgfplotstabletypeset\gtable
% Sort the second table by the x value, from largest to smallest
\pgfplotstablesort[sort cmp={float >}]\gsorted{\gtable}
%\pgfplotstabletypeset\gsorted
% Concatenate the tables -- now filledcurve contains the edge of
% a polygon bounded by curves f and g
\pgfplotstablevertcat{\filledcurve}{\ftable}
\pgfplotstablevertcat{\filledcurve}{\gsorted}
% Draw the curves and the polygon
\begin{tikzpicture}
\begin{axis}
\addplot[fill=gray!40,draw=none] table {\filledcurve};
\addplot[red] table {\ftable};
\addplot[blue] table {\gtable};
\end{axis}
\end{tikzpicture}

\end{document}
2
  • Thank you! Are there any advantages into using tables compared to Caramdir's solution (compilation time, accuracy etc)?
    – pmav99
    May 6, 2011 at 7:20
  • @pmav99: Flexibility. You can use a mathematical function for one of the boundaries, and a table of data points for the other, for example. You can just define the second table using something like \pgfplotstableread[row sep=\\]{x y\\0.5 1\\0.8 0.8\\1.5 0.9\\}\gtable. That would be quite hard to wrap into a mathematical expression.
    – Jake
    May 6, 2011 at 7:34
11
\documentclass[11pt]{article}
\usepackage{pst-plot}

\begin{document}

\begin{psgraph}{->}(0,0)(5,2.5){6cm}{5cm}
\pscustom[fillstyle=solid,fillcolor=black!20,
          linestyle=none]{
  \psplot[algebraic]{1}{4}{sqrt(x)}
  \psplot[algebraic]{4}{1}{sqrt(x/2)} }
\psplot[algebraic,linecolor=red,linewidth=1pt]{1}{4}{sqrt(x)}
\psplot[algebraic,linecolor=blue,linewidth=1pt]{4}{1}{sqrt(x/2)}
\end{psgraph}

\end{document}

enter image description here

1
  • 2
    This is not about pgfplots but thank you anyway!
    – pmav99
    May 6, 2011 at 7:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .