# How to use filling in ContourPlot

I want to fill region between different contours, e.g. ContourPlot[{c1 = f1, c2 = f2}, ...] a la the filling options for Plot like Filling -> {1->{2}}. Is it an easier way than superimposing two contour plots then manually excluding regions?

-
I think some times it will not be so clear for implicit functions to say something analogous to Filling -> {1->{2}}. eg. ContourPlot[{Cos[x] + Cos[y] == 1/2, Sin[x] + Cos[y] == 1/2}, {x, 0, 12}, {y, 0, 12}]. btw maybe it will be RegionPlot what you are looking for. –  Silvia Aug 5 '12 at 13:37

I think some times it will not be so clear for implicit functions to say something analogous to Filling -> {1->{2}} as it is in Plot. Anyway, maybe it will be RegionPlot what you are looking for. But in that case you might still need superimposing two Graphics.

Here is an example:

curvegraph =
ContourPlot[{Cos[x] + Cos[y] == 1/5, Sin[x] + Cos[y] == 1/10},
{x, 0, 4 Pi}, {y, 0, 4 Pi},
ContourStyle -> {Directive[Red, Thick], Directive[Blue, Thick]}];

RegionPlot[(Cos[x] + Cos[y] <= 1/5 &&
Sin[x] + Cos[y] >= 1/10) || (Cos[x] + Cos[y] >= 1/5 &&
Sin[x] + Cos[y] <= 1/10), {x, 0, 4 Pi}, {y, 0, 4 Pi},
PlotPoints -> 50, BoundaryStyle -> None,
PlotStyle -> Lighter[Orange, .9]];



-
It seems to be what the OP wanted, +1. –  Artes Aug 5 '12 at 14:07
Awesome answer - almost what I wanted! I was hoping for a nice option since it does get tedious writing the conditions for RegionPlot. Thanks for the pointer to RegionPlot though; now I just need to cook some automating functions. –  polyglot Aug 5 '12 at 14:13
@Artes Thanks :) I'm not sure what the OP exactly want. There could be many possibilities for implicit function curves.. –  Silvia Aug 5 '12 at 14:14
@polyglot Thanks. Though it looks not so trivial for me to fill areas between free curves automaticly.. Maybe you could introduce some dynamic things to manually specify (eg. using mouse/Locators etc.) areas you want to fill. –  Silvia Aug 5 '12 at 14:19

It seems you would rather use RegionPlot instead of ContourPlot.

Let's define e.g.

f[x_] := x^2 - x y + y^2 - 3
g[x_] := x^2 + 5 x y - 3 y^2 - 2


then

ContourPlot[{f[x] == 2, g[x] == 3}, {x, -5, 5}, {y, -5, 5}]


or one could use ContourPlot this way :

ContourPlot[f[x] - 2, {x, -5, 5}, {y, -5, 5}, Contours -> 11,
RegionFunction -> Function[{x, y}, g[x] - 3 < 0]]


while

RegionPlot[{f[x] - 2 > 0, g[x] - 3 < 0}, {x, -5, 5}, {y, -5, 5}]


or extracting only regions between curves

GraphicsGrid[ Table[ RegionPlot[ a[g[x] - 3, 0] && b[f[x] - 2, 0], {x, -5, 5}, {y, -5, 5},
Axes -> True, BoundaryStyle -> {Thick, Darker @ Green}],
{a, {Greater, Less}}, {b, {Greater, Less}}]]


-
+1, was just writing a same ting :) –  Silvia Aug 5 '12 at 13:57
@Silvia Thanks, questions while not well posed are interpretable in many different ways, however interpretations are sometimes close enough. –  Artes Aug 5 '12 at 14:03
ContourPlot[Sin[x] Sin[y], {x, -3, 3}, {y, -3, 3},
ContourLabels -> True, Contours -> {0.2, 0.4, 0.6, 0.8, -0.2, -0.4, -0.6, -0.8},
ContourShading -> {None, Lighter[Pink], Lighter[Blue], Lighter[Green]}]


-
As István points out on David's post, this answer has nothing to do with the OP's question, which is about filling between the contours of two equalities, not filling between the contours of a single function. –  Rahul Narain Jan 6 at 23:39

Taking into account István's comment and the nice example of Silvia, I used Presentations again (which I sell) to produce a filled plot using overlays with low opacity. The problem here is to convert the contour Lines into Polygons, both the Lines that meet a common edge of the plot and the Lines that span a corner. Here is the routine for that:

CompleteThePolygon[{{xmin_, xmax_}, {ymin_, ymax_}}] :=
Line[points : {first : {xfirst_, yfirst_}, __,
last : {xlast_, ylast_}}] :>
Module[{xcorner, ycorner},
Which[
first == last, Polygon[points],
xfirst == xlast || yfirst == ylast, Polygon[Join[points, {first}]],
True,
xcorner =
First[Select[{xfirst, xlast}, MatchQ[#, N[xmin | xmax]] &]];
ycorner =
First[Select[{yfirst, ylast}, MatchQ[#, N[ymin | ymax]] &]];
Polygon[Join[points, {{xcorner, ycorner}, first}]]]
]


Then this is the plot.

Draw2D[
{EdgeForm[Black],
MapThread[{#2, (ContourDraw[#1, {x, 0, 4 Pi}, {y, 0, 4 Pi}] //
Normal) /.
CompleteThePolygon[{{0, 4 \[Pi]}, {0, 4 \[Pi]}}]} &, {{Cos[x] +
Cos[y] == 1/5, Sin[x] + Cos[y] == 1/10}, {Opacity[0.4, Orange],
Opacity[0.3, Lighter@Blue]}}]},
AspectRatio -> Automatic,
Frame -> True,
PlotLabel -> "Lines to Polygons",
ImageSize -> 300
]


This may not be exactly what is wanted because it fills all the regions of overlap.

-

The solution of Beste and Sekto is pretty good and uses regular Mathematica. The only downside is the chore of picking all the filling colors.

One place where this consideration comes in is in a contour plot that has rather large plateaus with small variation in value that fill much of the area of the plot. The Presentations Application, which I sell, has a feature to automatically handle this. Here is a typical case:

<< Presentations
contourlist = {-1, -0.5, 0, 0.25, 0.5, 0.75, 0.85, 0.9, 0.925, 0.95,
0.99, 1};
Draw2D[
{ContourDraw[
Cos[(x + 1/2)^2 ( y - 1/2)] Cos[y], {x, -\[Pi]/2, \[Pi]/
2}, {y, -\[Pi]/2, \[Pi]/2},
Contours -> contourlist,
ColorFunction -> (ColorData["RedBlueTones"][1 - #] &),
ColorFunctionScaling -> False,
PlotRange -> Automatic]},
AspectRatio -> Automatic,
Frame -> True,
PlotLabel -> "Using Default Gradient Coloring",
ImageSize -> 300
]


The ContourColors ColorFunction will automatically pick distinguished colors based on the contour list.

contourlist = {-1, -0.5, 0, 0.25, 0.5, 0.75, 0.85, 0.9, 0.925, 0.95,
0.99, 1};
Draw2D[
{ContourDraw[
Cos[(x + 1/2)^2 ( y - 1/2)] Cos[y], {x, -\[Pi]/2, \[Pi]/
2}, {y, -\[Pi]/2, \[Pi]/2},
Contours -> contourlist,
ColorFunction ->
ContourColors[contourlist, ColorData["RedBlueTones"][1 - #] &],
ColorFunctionScaling -> False,
PlotRange -> Automatic]},
AspectRatio -> Automatic,
Frame -> True,
PlotLabel -> "Using a ContourColors",
ImageSize -> 300
]
`

-
David, I think your answer (and @Beste's) has nothing to do with the OP's question: that is about filling between the contours of two equalities instead of filling between the contours of a single function. –  István Zachar Jan 6 at 17:42