26

I would like to plot two (rather simple) functions f, g over domain -2:2 and fill the area between them. The fill color should be red if f > g and green if f < g (for example), and in later stage also shaded depending the x coordinate (to show weighting of the difference).

So far I got to filling the area between them with uniform color with

\documentclass{minimal}
\usepackage{tikz,pgfplots}
\begin{document}
\tikz[scale=.6,domain=-2:2]{
    \begin{axis}[axis on top=false, axis x line=middle, axis y line=middle,stack plots=y]
        % plot first function
        \addplot+[mark=none] {.55*x+.13} \closedcycle;
        % substract first function from the second one, since they are stacked, and fill that area
        \addplot+[mark=none,fill] {.2*x^3-.05*x^2+.2-(.55*x+.13)} \closedcycle;
        \addplot+[mark=none] {0} \closedcycle; % should make the second function visible?
    \end{axis}
}
\end{document}

result of the source above

with the following problems/questions:

  1. the second function is not shown, it is only border of the filled area
  2. how to make the fill color different depending on the sign of the difference?
  3. how to shade it depending on x?
  4. would I finally be better off using plain TikZ, perhaps specifying the functions as splines?

3 Answers 3

20

Following your idea (I don't know pgfplots very much), you could stack successively the positive part and the negative part of the difference of the two functions.

As the following code shows, it is not perfect, but it works. Note that I have increased the sample size in order to smooth the sign-changing parts.

\documentclass{minimal}
\usepackage{tikz,pgfplots}
\begin{document}
\tikz[scale=.6,domain=-2:2,samples=50]{
    \begin{axis}[axis on top=false, axis x line=middle, axis y line=middle,stack plots=y]
        % plot first function
        \addplot+[mark=none] {.55*x+.13};
        % substract first function from the second one, since they are stacked, and plot successively the positive and negative parts
        \addplot+[mark=none,fill=red,draw=black] {max(.2*x^3-.05*x^2+.2-(.55*x+.13),0)} \closedcycle;
        \addplot+[mark=none,fill=green,draw=black] {min(.2*x^3-.05*x^2+.2-(.55*x+.13),0)} \closedcycle;
    \end{axis}
}
\end{document}

enter image description here

10

For the record, I came up with the following myself (different color of positive and negative parts is not handled, but gradient is):

\tikz[scale=.6,domain=-2:2]{
    % use splines instead of functions
    \def\pSpec{ (-2,-1.8) .. controls (-1,2.5) and (.5,-1.7) .. (2,1.6) }
    \def\qSpec{ (2,1.3) -- (-2,-.8) } % specify backwards, easy
    % this a workaround because I don't know how to make gradient which is white at boundaries and red in the middle :-|
    \begin{scope} % fill the whole with white->red gradient, and clip just the left part
        \clip (-2,-2) rectangle (2,4);
        \shadedraw[left color=white,right color=red] \pSpec -- \qSpec -- cycle;
    \end{scope}
    \begin{scope} % right part, red fading to the right
        \clip (0,-2) rectangle (2,4);
        \shadedraw[left color=red,right color=white] \pSpec -- \qSpec -- cycle;
    \end{scope}
    }
    \draw[very thin] (-2,-2) grid (2,2);
    \draw[->] (-2.2,0)--(2.2,0) node[right] {$x$};
    \draw[->] (0,-2.2)--(0,2.2) node[above] {$y$};
    \draw[color=blue,thick] \pSpec node[right] {$p$};
    \draw[color=brown,thick] \qSpec node[left] {$q$};
    \draw[<->,thick] (-2,-1) -- node[below right] {$\Omega$} (2,-1);
}

Looks like this in beamer:

result as rendered with beamer

8

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}
\tikz[scale=.6,domain=-2:2]{
    \begin{axis}[axis on top=false, axis x line=middle, axis y line=middle]
        % plot first function
        \addplot+[name path=A,mark=none] {.55*x+.13};
        \addplot+[name path=B,mark=none] {.2*x^3-.05*x^2+.2};

        \addplot fill between[
            of=A and B,
            split,
            every odd segment/.style={red,left color=red,right color=white},
            every even segment/.style= {green,left color=green, right color=white},
        ];
    \end{axis}
}
\end{document}

The solution requires two steps: in a first step, the two input plots are labelled using name path. The second step is to generate the filled path using \addplot fill between. The mandatory option is of=A and B. In our case, we want to split the fill path into individual path segments. The option split enables this splitting. Finally, the two style definitions allow to visualize the individual segments with different options.

Note that \addplot fill between is drawn on a separate layer |pre main|.

You must log in to answer this question.

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