11

I am new with Mathematica, but am trying to fill an area between two parametric plots

ParametricPlot[{{u + Sin[u], -Cos[u]}, {u + Sin[u + Pi], Cos[u + Pi]}}, 
{u, 0, Pi}, Axes -> True ]

which thus far are nice, clean curves:

1

Thanks to the answers here: How do I fill in a circle made by ParametricPlot with one solid color? I became aware of ListLinePlot.

However, my ListLinePlot for this situation

ListLinePlot[Table[{{u + Sin[u], -Cos[u]}, {u + Sin[u + Pi], Cos[u + Pi]}},
{u, 0, Pi, 0.0005}], Mesh -> All, 
MeshStyle -> Directive[AbsolutePointSize[0.0005], Black], 
PlotStyle -> Directive[Thin, LightGray]]

2

does not seem to give as good a resolution no matter how finely I subdivide the interval, and also produces problems with self-intersection near the boundaries when plotting several periods. In particular, the contrast with similar curves filled in Plot is striking.

Is there a smarter way to fill the area between these parametric curves? Perhaps using something else than ListLinePlot? Thanks!

bob7294
  • 121
  • 1
  • 6
  • 2
    Don't accept my answer all too quickly! I am sure there are other approaches, give them a chance too :) (by the way: welcome to mathematica.se, great way to present a first question!) – Pinguin Dirk Sep 04 '13 at 19:25
  • Thanks for the welcome, and the helpful answer. Using ParametricPlot in the way you suggest gives me full resolution, without the somewhat artificial contrivance of ListLinePlot drawing vertical lines between the two data sets to fill the area. I have tentatively "unaccepted" to allow other people to give their input, but hope to reverse that soon :). – bob7294 Sep 04 '13 at 19:32
  • 1
    Great! Note that you got the vertical lines as you missed to Transpose your data in ListLinePlot, thus it connected 2 points of each curve instead of the points on the curve. See ListLinePlot docu. I also added more info in my answer (and don't forget, you can still upvote :) ) – Pinguin Dirk Sep 04 '13 at 19:44
  • Your own "filling" solution using ListLinePlot is quite ingenious IMHO. :-) – Mr.Wizard Sep 05 '13 at 01:43

6 Answers6

10

ParametricPlot

Here's a way that seems to work in your case (see below in @ssch's (thanks!) comments when it doesn't)

Let (for better readability)

f1[u_] := {u + Sin[u], -Cos[u]}
f2[u_] := {u + Sin[u + Pi], Cos[u + Pi]}

And then

ParametricPlot[{ v f1[u] + (1 - v) f2[u]}, {u, 0, Pi}, {v, 0, 1}, 
   Axes -> True, Mesh -> None, PlotStyle -> LightGray]

i.e., we just add an auxiliary parameter v, to "shift" between the curves.

enter image description here

Using ColorFunction, you can add more colors:

ParametricPlot[{v f1[u] + (1 - v) f2[u]}, {u, 0, Pi}, {v, 0, 1}, 
  Axes -> True, Mesh -> None, ColorFunction -> Function[{x, y, u, v}, Hue[v]]]

(I won't paste a picture of that here)


ListLinePlot

For ListLinePlot, note that your data is wrongly formatted, try e.g.:

ListLinePlot[
   Transpose@Table[{{u + Sin[u], -Cos[u]}, {u + Sin[u + Pi], Cos[u + Pi]}}, 
      {u, 0, Pi, 0.01}], Filling -> {1 -> {2}}]

Note the Transpose I added to fix the issue.

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
Pinguin Dirk
  • 6,519
  • 1
  • 26
  • 36
  • 2
    Visualization of the ParametricPlot procedure: Manipulate[ ParametricPlot[{ v f1[u] + (1 - v) f2[u], f1[u], f2[u]}, {u, 0, Pi}, Epilog -> { Point[{f1[û], f2[û]}], Line[{f1[û], f2[û]}]}] , {{v, .5}, 0, 1} , {{û, 2.}, 0, Pi}] – ssch Sep 04 '13 at 20:08
  • 3
    More instructive when it fails: f1[u_] := {u + Sin[u], -Cos[u]}; f2[u_] := {u + Sin[u + Pi], Cos[2 (u - Pi/2) + Pi]}; pp = ParametricPlot[{v f1[u] + (1 - v) f2[u]}, {u, 0, Pi}, {v, 0, 1}, Mesh -> None]; Manipulate[ Show[ pp, Epilog -> {Line[{f1[u], f2[u]}]} ], {{u, 0.5}, 0, Pi}] – ssch Sep 04 '13 at 20:22
  • I guess I have to put "in your case" in bold... thanks for pointing that out explicitly, thanks @ssch – Pinguin Dirk Sep 04 '13 at 20:26
  • How would you do it if instead of two curves there were several that form a closed loop ? – Daniel Castro Mar 01 '22 at 13:49
10

Similar to @ybeltukov, you can extract the lines from the plot. But to get a proper polygon, you need to reverse one of the lines.

plot = ParametricPlot[{{u + Sin[u], -Cos[u]}, {u + Sin[u + Pi], 
     Cos[u + Pi]}}, {u, 0, Pi}, Axes -> True];
{line1, line2} = Cases[plot, l_Line :> First@l, Infinity];

Graphics[
 {Opacity[0.4], Darker@Blue, EdgeForm[Darker@Blue], 
  Polygon[Join[line1, Reverse@line2]]},
 Options[plot]
 ]

Mathematica graphics

Then one can style the polygon and/or lines as desired.

Graphics[
 {{Opacity[0.4], ColorData[1][3], 
   Polygon[Join[line1, Reverse@line2]]}, Thick, ColorData[1][1], 
  Line@line1, ColorData[1][2], Line@line2},
 Options[plot]
 ]

Mathematica graphics

Michael E2
  • 235,386
  • 17
  • 334
  • 747
8

A subtly different ListLinePlot approach:

ListLinePlot[{
      Table[{u + Sin[u], -Cos[u]}, {u, 0, Pi, 0.005}],
      Table[{u + Sin[u + Pi], Cos[u + Pi]}, {u, 0, Pi, 0.005}]},
          Filling -> {1 -> {{2}, LightGray}}, PlotStyle -> Black]

It looks better to me in terms of jaggies:

enter image description here

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
george2079
  • 38,913
  • 1
  • 43
  • 110
  • Thanks. I think this addresses the issue pointed out by Pinguin Dirk in the comments as well as in his answer: my ListLinePlot data needs to be transposed - the resolution problems stem from this. – bob7294 Sep 04 '13 at 20:26
  • This is the same way I thought of. +1 – Mr.Wizard Sep 05 '13 at 01:46
6

I think you can use Piecewise and the approach in your link How do I fill in a circle made by ParametricPlot with one solid color?

ParametricPlot[
 {Piecewise[{{u + Sin[u], u < Pi}, {u - Pi + Sin[u], u > Pi}}], 
  Piecewise[{{-Cos[u], u < Pi}, {Cos[u], u > Pi}}]}, 
 {u, 0, 2 Pi}, Axes -> True] /. Line[l_List] :> {{Red, Polygon[l]}, {Black, Line[l]}}

parametric plot

ybeltukov
  • 43,673
  • 5
  • 108
  • 212
3

Use separate table for each curve or transpose the table, then use filling.

ListLinePlot[
 Table[#, {u, 0, Pi, Pi/100}] & /@  {{u + Sin[u], -Cos[u]},
                                     {u + Sin[u + Pi], Cos[u + Pi]}},
 Filling -> {1 -> {2}}, FillingStyle -> GrayLevel[.95]];

ListLinePlot[
 Transpose[Table[{{u + Sin[u], -Cos[u]}, {u + Sin[u + Pi], Cos[u + Pi]}},
                 {u, 0, Pi, Pi/100}]],
 Filling -> {1 -> {2}}, FillingStyle -> GrayLevel[.95]]

enter image description here

Kuba
  • 136,707
  • 13
  • 279
  • 740
Bob Hanlon
  • 157,611
  • 7
  • 77
  • 198
0

I tried just :

ListLinePlot[
 Table[#, {u, 0, Pi, Pi/100}] & /@  {{u + Sin[u], -Cos[u]},
                                 {u + Sin[u + Pi], Cos[u + Pi]}},
 Filling -> {1 -> {2}}, FillingStyle -> Green[.95]];

And it made the same figure but the color of filling is blue between the curves. So why do you need the transpose version also?