Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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)

share|improve this question

4 Answers 4

up vote 10 down vote accepted

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.

share|improve this answer

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}
share|improve this answer
    
Thank you Caramdir. I knew there had to be a simple way! –  pmav99 May 6 '11 at 7:21
    
Is there any way to label the filled regions? or draw arrows or something to them? –  gekkostate Jan 23 at 19:39
\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

share|improve this answer
2  
This is not about pgfplots but thank you anyway! –  pmav99 May 6 '11 at 7:19

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}
share|improve this answer
    
Thank you! Are there any advantages into using tables compared to Caramdir's solution (compilation time, accuracy etc)? –  pmav99 May 6 '11 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 '11 at 7:34

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.