18
$\begingroup$

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?

$\endgroup$
1
  • $\begingroup$ 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. $\endgroup$
    – Silvia
    Commented Aug 5, 2012 at 13:37

5 Answers 5

23
$\begingroup$

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]}];

shadinggraph = 
  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]];

Show[{shadinggraph, curvegraph}]

Mathematica graphics

$\endgroup$
4
  • $\begingroup$ It seems to be what the OP wanted, +1. $\endgroup$
    – Artes
    Commented Aug 5, 2012 at 14:07
  • $\begingroup$ 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. $\endgroup$
    – polyglot
    Commented Aug 5, 2012 at 14:13
  • $\begingroup$ @Artes Thanks :) I'm not sure what the OP exactly want. There could be many possibilities for implicit function curves.. $\endgroup$
    – Silvia
    Commented Aug 5, 2012 at 14:14
  • $\begingroup$ @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. $\endgroup$
    – Silvia
    Commented Aug 5, 2012 at 14:19
10
$\begingroup$

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}]

enter image description here

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]]

enter image description here

while

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

enter image description here

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}}]]

enter image description here

$\endgroup$
1
  • $\begingroup$ @Silvia Thanks, questions while not well posed are interpretable in many different ways, however interpretations are sometimes close enough. $\endgroup$
    – Artes
    Commented Aug 5, 2012 at 14:03
2
$\begingroup$

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
 ]

enter image description here

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

$\endgroup$
1
$\begingroup$
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]}]

Mathematica graphics

$\endgroup$
1
  • 1
    $\begingroup$ 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. $\endgroup$
    – user484
    Commented Jan 6, 2014 at 23:39
-2
$\begingroup$

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
 ]

enter image description here

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
 ]

enter image description here

$\endgroup$
1
  • 3
    $\begingroup$ 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. $\endgroup$ Commented Jan 6, 2014 at 17:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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