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.

I am loading two curves from a file and plot them with \addplot table [...] {the table.txt}; I have managed to fill the area under a single curve, but I want the minimum of the two curves filled. What is the preferred way to accomplish this using tikz and pgfplots? The image shows an example of the desired result.

Thanks for any help.

enter image description here

share|improve this question

3 Answers 3

up vote 11 down vote accepted

This can be done by the fillbetween library which is shipped with pgfplots version 1.10:

enter image description here

\documentclass{standalone}

\usepackage{pgfplots}

\pgfplotsset{compat=1.9}

% \usetikzlibrary{}
\usepgfplotslibrary{fillbetween}


\begin{document}

\begin{tikzpicture}
    \begin{axis}[axis on top,set layers]
    \addplot[blue,name path=A,domain=0:2.3] {sin(deg(2*x))};    

    \addplot[red,name path=B,domain=0:2.3] {cos(deg(2*x))};

    \pgfonlayer{pre main}
    \fill[blue!20!white,intersection segments={of=A and B,sequence={A0 -- B1 -- A2}}]
        -- (axis cs:2.3,\pgfkeysvalueof{/pgfplots/ymin})
        -- (axis cs:0,\pgfkeysvalueof{/pgfplots/ymin})
        -- cycle
    ;
    \endpgfonlayer
    \end{axis}
\end{tikzpicture}
\end{document}

The idea is to use the new intersection segments path instructions provided by fillbetween. It accepts to labelled paths on input and a sequence of intersection segments. Currently, the "minimum" needs to be provided manually. In your case, you need to use the first (0th) segment of the first (A) curve (A0), then the second (1st) of the second curve (B) which is B1, followed by the third (2rd) segment of the first curve which is A2. The other statements specify the bottom line of the filled region. The layering instructions set layers and \pgfonlayer make sure that the stuff appears behind the labelled input paths.

Note that version 1.10 is very young at the time of this writing - you might need a software upgrade.

share|improve this answer
    
Ok, so you have to manually add to sequence={A0 -- B1 -- A2} if there are more intersections, B3 -- A4 -- B5 etcetera? As my data comes from a table, would you say it is just better to have an extra column with the minimum of my two functions? –  Godisemo Mar 14 at 9:32
    
Well, if you have the two functions sampled at the same points, you could easily let pgfplots compute the minimum and draw a separate plot with the minimum and \closedcycle. My solution is better if the curves do not have the same sample points. –  Christian Feuersänger Mar 14 at 9:36
    
In my case they are sampled at the same points. What is the function I would use for computing the minimum inside pgfplots, rather than adding an extra column to my input file? Thanks for the help and for an awesome package! –  Godisemo Mar 14 at 9:42
    
Just for future reference, I managed to do what I wanted using the y expr key and section 4.3.4 "Mathematical Expressions And File Data" in the pgfplots 1.10 manual. I'll mark this anser as accepted. –  Godisemo Mar 14 at 9:59
    
@Godisemo could you add your own answer as well? While I am excited about the new fillbetween stuff, your example might actually be a simpler and more automatic solution. It will help visitors to see the different solutions. –  Christian Feuersänger Mar 14 at 14:18

Another alternative is use of the clip twice, without fillbetween library. First, fill the area below sine curve and then clean the area above cosine curve.

enter image description here

Code:

\documentclass{article}
\usepackage[papersize={11cm,10cm}]{geometry}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\thispagestyle{empty}

\begin{document}

\begin{tikzpicture} 
\begin{axis}[enlargelimits=0.1]
\begin{scope}
\clip(axis cs:0,-1.19) -- (axis cs:2.3,-1.19) -- (axis cs:2.3,1)-- (axis cs:0,1)--  cycle;
\addplot[draw=white,fill=blue!20!white,domain=0:2.3] {sin(deg(2*x))}--(axis cs:2.3,-1.5) --(axis cs:0,-1.5);    
\end{scope}

\begin{scope}
\clip (axis cs:2.3,-1) -- (axis cs:2.3,1) -- (axis cs:0,1)-- (axis cs:0,-1)--cycle;
\addplot[draw=white,fill=white,domain=0:2.3] {cos(deg(2*x))}--(axis cs:2.3,1)--(axis cs:0,1);
\end{scope}
\addplot[red,domain=0:2.3] {cos(deg(2*x))};
\addplot[blue,domain=0:2.3] {sin(deg(2*x))};
\end{axis}
\end{tikzpicture}  
\end{document}
share|improve this answer

Just for finalizing the question with PSTricks.

Postfix representation

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-plot,pst-eucl}

\def\f{x RadtoDeg sin 2 mul 3 add}
\def\g{x RadtoDeg cos 2 mul 3 add}

\begin{document}
\begin{pspicture}[saveNodeCoors,PointName=none,PointSymbol=none](-1,-1)(7,6)
    \pstInterFF{\f}{\g}{1}{A}
    \pstInterFF{\f}{\g}{4}{B}
    \pscustom[linestyle=none,fillstyle=solid,fillcolor=lightgray]
    {
        \psplot{.5}{N-A.x}{\f}
        \psplot{N-A.x}{N-B.x}{\g}
        \psplot{N-B.x}{6}{\f}
        \psline(6,0)(.5,0)
        \closepath
    }
    \psaxes[ticks=none,labels=none]{->}(0,0)(-1,-1)(6.5,5.5)[$x$,0][$y$,90]
    \psplot[linecolor=blue]{0}{TwoPi}{\f}
    \psplot[linecolor=red]{0}{TwoPi}{\g}
\end{pspicture}
\end{document}

enter image description here

Infix representation

If you prefer to work in infix, use the following.

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-plot,pst-eucl}

\def\f{(2*sin(x)+3)}
\def\g{(2*cos(x)+3)}

\pstVerb{/I2P {AlgParser cvx exec} def}

\begin{document}
\begin{pspicture}[algebraic,saveNodeCoors,PointName=none,PointSymbol=none](-1,-1)(7,6)
    \pstInterFF{\f I2P}{\g I2P}{1}{A}
    \pstInterFF{\f I2P}{\g I2P}{4}{B}
    \pscustom[linestyle=none,fillstyle=solid,fillcolor=lightgray]
    {
        \psplot{.5}{N-A.x}{\f}
        \psplot{N-A.x}{N-B.x}{\g}
        \psplot{N-B.x}{6}{\f}
        \psline(6,0)(.5,0)
        \closepath
    }
    \psaxes[ticks=none,labels=none]{->}(0,0)(-1,-1)(6.5,5.5)[$x$,0][$y$,90]
    \psplot[linecolor=blue]{0}{TwoPi}{\f}
    \psplot[linecolor=red]{0}{TwoPi}{\g}
\end{pspicture}
\end{document}
share|improve this answer

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.