32
$\begingroup$

Since PolarPlot doesn't support Filling, what is the best way to shade or fill the a region between two polar curves?

For instance, how would I generate a version of the following graph with the region inside the first curve but outside the second curve filled?

PolarPlot[{{1, -1} Sqrt[2 Cos[t]], 2 (1 - Cos[t])}, {t, -\[Pi], \[Pi]}]

Mathematica graphics

$\endgroup$
6
  • 1
    $\begingroup$ In the first one there are two curves ... :) $\endgroup$ May 4, 2012 at 1:18
  • $\begingroup$ @belisarius: :) okay, true, but I was actually dealing with r^2==2Cos[t] as my first curve and for purposes of the region to be shaded, we could actually toss out the negative square root part. $\endgroup$
    – Isaac
    May 4, 2012 at 1:21
  • $\begingroup$ It appears I misunderstood the question. Should I leave my answer or delete it? Perhaps it illustrates something of value. $\endgroup$
    – Mr.Wizard
    May 4, 2012 at 5:31
  • $\begingroup$ @Mr.Wizard: It definitely adds value—if you take out the Reverse@, the part left in white is the part I'd wanted to shade, so with only a little more tweaking, I can get it to do what I'd wanted. $\endgroup$
    – Isaac
    May 4, 2012 at 6:07
  • $\begingroup$ Thanks. Though not robust at least that is on-topic; I'll add it to the answer. $\endgroup$
    – Mr.Wizard
    May 4, 2012 at 6:43

10 Answers 10

28
$\begingroup$

You have a (or more) curves. If you don't use PolarPlot you could use ParametricPlot instead but you would have to make the transformation from polar coordinates by yourself.

Knowing this, you could think about what your functions mean. For instance 2 (1 - Cos[phi]) is just the radius of your curve for a given phi. If you want to draw the region outside your curve, the only thing you have to do is (attention, I'm mixing polar and Cartesian coord.):

Check a every point $\{x,y\}$ whether the radius $\sqrt{x^2+y^2}$ is larger than $2(1-\cos(\varphi))$ where $\varphi=\arctan(y/x)$.

Using this, your filling can be achieved with RegionPlot and your graphics

Show[
 PolarPlot[Evaluate[{{1, -1} Sqrt[2 Cos[t]], 
   2 (1 - Cos[t])}], {t, -\[Pi], \[Pi]}],
 RegionPlot[
  Sqrt[x^2 + y^2] > 2 (1 - Cos[ArcTan[x, y]]) &&
  Sqrt[x^2 + y^2] < Re@Sqrt[2 Cos[ArcTan[x, y]]]
  , {x, -2, 2}, {y, -3, 3}],
 PlotRange -> All
 ]

enter image description here

If you encounter dark mesh lines in the filling and want to get rid of them, please read the question of david here. You then have to include

Method -> {"TransparentPolygonMesh" -> True}

as option.

$\endgroup$
6
  • $\begingroup$ This no longer seems to work in Mathematica 10.2. $\endgroup$
    – David
    Aug 14, 2015 at 17:07
  • $\begingroup$ @David Fixed it. The behavior-change is not documented $\endgroup$
    – halirutan
    Aug 17, 2015 at 0:59
  • $\begingroup$ You need to add Method -> {"TransparentPolygonMesh" -> True} at the end. $\endgroup$
    – David
    Aug 17, 2015 at 4:54
  • $\begingroup$ @David Why would I need it? For me on Linux with Mathematica version 10.2 it looks like this which is except of the default colors exactly what the OP asked for. $\endgroup$
    – halirutan
    Aug 17, 2015 at 10:55
  • $\begingroup$ If you look at the first image at http://mathematica.stackexchange.com/questions/91634/mathematica-10-2-problem-with-shading-between-polar-graphs?noredirect=1#comment249007_91634 you will see that the shaded region has a whole bunch of mesh lines. Your new code has those mesh lines on the mac (and probably windows) in Mathematica 10.2. The Method -> {"TransparentPolygonMesh" -> True} gets rid of those mesh lines. $\endgroup$
    – David
    Aug 17, 2015 at 14:59
22
$\begingroup$

Even if Filling were an option in PolarPlot, you won't be able to create such a plot because for 2D graphics, Filling just blindly fills along the y-axis, whereas you need to check for an inequality here.

That said, here's another approach that's in the same spirit as halirutan's, but you don't have to convert to Cartesian, etc.

eqns[t_] := { Sqrt[2 Cos[t]], 2 (1 - Cos[t])};
region = PolarPlot[Evaluate@eqns[t], {t, -π, π}, 
    RegionFunction -> Function[{x, y, t, r}, {#1 > #2} & @@ Re[eqns[t]] // First]];
pts = Cases[region, Line[x___] :> x, Infinity];
colors = {Darker@Green, Blue};

Show[
    PolarPlot[Evaluate@eqns[t], {t, -π, π}, PlotStyle -> colors], 
    ListLinePlot[pts, PlotStyle -> colors, Filling -> Axis, FillingStyle -> LightGreen], 
    PlotRange -> All
]

enter image description here

$\endgroup$
6
17
$\begingroup$

Just another way:

<< VectorAnalysis`;
{rho, t, z} = CoordinatesFromCartesian[{x, y, z}, Cylindrical]
Quiet@Show[
  PolarPlot[{ Sqrt[2 Cos@t], 2 (1 - Cos@t)}, {t, -Pi, Pi}],
  RegionPlot[ Sqrt[2 Cos@t] > rho > 2 (1 - Cos@t), {x, 0, 2}, {y, -1, 1}]]

Mathematica graphics

$\endgroup$
16
$\begingroup$

Yet another way. It's similar to belisarius's solutions but doesn't require an inverse coordinate transformation

Show[
 PolarPlot[{Sqrt[2 Abs[Cos[t]]], 2 (1 - Cos[t])}, {t, -\[Pi], \[Pi]}], 
 RegionPlot[4 (1 - Cos[t])^2 < r^2 < 2 Cos[t], {r, 0, 3}, {t, -Pi, Pi},
  PlotPoints -> 30] /. 
   GraphicsComplex[a_, b__] :> GraphicsComplex[#1 {Cos[#2], Sin[#2]} & @@@ a, b]]

Mathematica graphics

$\endgroup$
15
$\begingroup$

You can parameterize your polar functions on to discs, and then shade appropriately.

ρ[t_] := Sqrt[2 Cos[t]];
σ[t_] := 2 (1 - Cos[t]);
ParametricPlot[{{r Cos[t] ρ[t], r Sin[t] ρ[t]}, {r Cos[t] σ[t], r Sin[t] σ[t]}}, 
    {t, -π, π}, {r, 0, 1}, PlotStyle -> {{Opacity[.5], Red}, {Opacity[1], White}}, 
    Mesh -> None, PlotRange -> All]

enter image description here

$\endgroup$
14
$\begingroup$

How about

dt = Pi/99;
pts = Join[
   Table[2 (1 - Cos[t]) {Cos[t], Sin[t]},
    {t, 0, -Pi/3 + dt, -dt}],
   Table[Sqrt[2 Cos[t]] {Cos[t], Sin[t]},
    {t, -Pi/3, Pi/3, dt}],
   Table[2 (1 - Cos[t]) {Cos[t], Sin[t]},
    {t, Pi/3, dt, -dt}]
   ];
PolarPlot[{Sqrt[2 Cos[t]], 2 (1 - Cos[t])}, {t, -\[Pi], \[Pi]},
 Prolog -> {LightGray, Polygon[pts]},
 PlotStyle -> Thick]

enter image description here

$\endgroup$
14
$\begingroup$

Here's a meager attempt that will soon be humiliated by Heike's answer. ;-)

g = PolarPlot[Evaluate@{{1, -1} Sqrt[2 Cos[t]], 
    2 (1 - Cos[t])}, {t, -\[Pi], \[Pi]}];

Graphics[{
   {Pink, Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]},
   Thread@{{White, Green, Blue}, 
     Reverse@Cases[g, Line[x__] :> Polygon[x], ∞]}
   }];

Show[g, %, g]

Mathematica graphics


Seeing as I misunderstood the question, here is an admittedly fragile way to shade the correct region:

g = PolarPlot[Evaluate@{{1, -1} Sqrt[2 Cos[t]], 2 (1 - Cos[t])}, {t, -\[Pi], \[Pi]}];

f = Graphics[Thread@{{Yellow, White, White}, Cases[g, Line[x__] :> Polygon[x], ∞]}];

Show[g, f, g]

Mathematica graphics

$\endgroup$
4
  • $\begingroup$ @MrWizard This no longer seems to work in Mathematica 10.2. $\endgroup$
    – David
    Aug 14, 2015 at 17:35
  • $\begingroup$ @David Thanks for the warning. These still work in 10.1 under Windows; can you try to figure out what changed? $\endgroup$
    – Mr.Wizard
    Aug 14, 2015 at 23:35
  • $\begingroup$ Sorry, I don't know what the problem is, just experienced it, but Michael E2 may be doing some work here. $\endgroup$
    – David
    Aug 15, 2015 at 19:59
  • 1
    $\begingroup$ Added Evaluate to your code and it now works to give the posted images. $\endgroup$
    – David
    Aug 17, 2015 at 15:11
12
$\begingroup$

Combining ListLinePlot, Filling and Overlay:

   pnts = Cases[
      PolarPlot[{{1, -1} Sqrt[2 Cos[t]], 2 (1 - Cos[t])}, {t, -\[Pi], \[Pi]}],
     _Line, {0, Infinity}];
   Table[ListLinePlot[{Join[pnts[[1, 1]], pnts[[2, 1]]], pnts[[3, 1]]}, 
     Filling -> fllng, PlotStyle -> {Red, Green},  AspectRatio -> 1], 
   {fllng, {Automatic, {1 -> {Axis, White}}, {2 -> {Axis, White}}, {1 -> {Axis, Red}},
    {2 -> {Axis, Green}}}}]

gives

enter image description here

With Overlay and

  GraphicsRow[{Overlay[%[[{4, 3}]]], Overlay[%[[{5, 2}]]]}]

we get

enter image description here

$\endgroup$
1
  • $\begingroup$ Your code no longer produces these images in Mathematica 10.2. Using PolarPlot[Evaluate@{{1, -1} Sqrt[2 Cos[t]], 2 (1 - Cos[t])} does produce your images. $\endgroup$
    – David
    Aug 17, 2015 at 15:15
1
$\begingroup$

I've used an general and light method, using polygons:

regionpoly[cv1_,cv2_,a_,b_,n_: 30,op_:0.5,col_: Green] := Module[{polys, ds},
       ds = N[(b - a)/n];
       polys = Table[Polygon[{
           cv1 /. {t -> dt}, 
           cv1 /. {t -> dt + ds}, 
           cv2 /. {t -> dt + ds},
           cv2 /. {t -> dt}, 
           cv1 /. {t -> dt} }],
           {dt, a, b - ds, ds}];
       (*Return*)
       {EdgeForm[], FaceForm[col], Opacity[op], polys}
       ];

    r1[t_] = Sqrt[2 Cos[t]]*{Cos[t], Sin[t]};
    r2[t_] = 2 (1 - Cos[t])*{Cos[t], Sin[t]};

    Show[{
      Graphics[  regionpoly[r1[t], r2[t], -Pi/3, Pi/3] ],
      PolarPlot[{Sqrt[2 Cos[t]], 2 (1 - Cos[t])}, {t, 0, 2 Pi}]                     
      }, Axes -> True, AxesStyle -> Arrowheads[0.04]]

enter image description here

$\endgroup$
0
$\begingroup$
Show[PolarPlot[{-Sqrt[2 Cos[t]],Sqrt[2 Cos[t]],2(1-Cos[t])},{t,-\[Pi],\[Pi]}],ParametricPlot[r {Cos[t],Sin[t]},{t,-Pi/3,Pi/3},{r,Min[a={Sqrt[2 Cos[t]],2(1-Cos[t])}],Max[a]}],PlotRange->All]
$\endgroup$

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.