5
$\begingroup$

I'm using Mathematica v7, in which the following code plots an ellipse (many thanks to @Kirma ):

With[{foci = {{3, 2}, {5, 1}},
  semimajoraxis = 1.7},
 Show[
  ContourPlot[
   Sum[EuclideanDistance[{x, y}, p], {p, foci}] == 2 semimajoraxis, 
   Evaluate[
    Sequence @@ 
     MapThread[{#1, #2 - semimajoraxis, #2 + semimajoraxis} &, {{x, 
        y}, Mean[foci]}]], AspectRatio -> Automatic, 
   ContourStyle -> {Blue}]]]

How can I use ContourPlot to omit one part of this contour and colour a second part red and a third part blue?

For example, how can I omit the part for which $x+y-4<0$ and, of what remains, colour the part for which $x+2y-8>0$ red and the other part blue?

$\endgroup$
  • $\begingroup$ for the first part of your question, you can use RegionFunction -> (# + #2 - 3.5< 0 &) (but this does not remove any part of the contour). $\endgroup$ – kglr Aug 27 '18 at 22:19
  • $\begingroup$ Thanks for this. I made a mistake with the linear inequalities, which I have now corrected. $\endgroup$ – ruffle Aug 27 '18 at 22:26
4
$\begingroup$

You can use RegionFunction to remove some parts of the graphics. To color different portions of the remaining part, you can produce two different plots using ConditionalExpression in the first argument. The two plots correspond to whether or not the condition #[[1]] + 2 #[[2]] - 5 >= 0 is satisfied:

sel = #[[1]] + 2 #[[2]] - 5 >= 0 &;
regf = (# + #2 - 6 < 0 &);
With[{foci = {{3, 2}, {5, 1}}, semimajoraxis = 1.7}, 
 Show[ContourPlot[ConditionalExpression[Sum[EuclideanDistance[{x, y}, p], {p, foci}], 
   #[{x, y}]] == 2 semimajoraxis, 
  Evaluate[Sequence @@ MapThread[{#1, #2 - semimajoraxis, #2 + semimajoraxis} &, 
    {{x, y}, Mean[foci]}]], AspectRatio -> Automatic, 
  ContourStyle -> Directive[#2, Thick], 
  RegionFunction -> regf] & @@@ {{sel, Red}, {Not[sel@#] &, Blue}}]]

enter image description here

Alternatively, you can post-process ContourPlot output to (1) extract contour line coordinates, (2) create a BSplineFunction from extracted coordinates, and (3) use it with ParametricPlot with a combination of Mesh* options and RegionFunction:

cp = With[{foci = {{3, 2}, {5, 1}}, semimajoraxis = 1.7}, 
   ContourPlot[Sum[EuclideanDistance[{x, y}, p], {p, foci}] == 2 semimajoraxis, 
    Evaluate[Sequence @@ MapThread[{#1, #2 - semimajoraxis, #2 + semimajoraxis} &, 
      {{x, y}, Mean[foci]}]], 
  AspectRatio -> Automatic, ContourStyle -> Directive[Blue, Thick]]];

meshf = # + 2 #2 - 5 &;
bsF = BSplineFunction[Join @@ Cases[Normal@cp, Line[x_] :> x, Infinity]];
ParametricPlot[bsF[t], {t, 0, 1}, PlotStyle -> Directive[Red, Thick], 
 MeshFunctions -> {meshf}, Mesh -> {{0}}, MeshStyle -> PointSize[0], 
 MeshShading -> Thread[Directive[{Blue, Red}, Thick]], Frame -> True, 
 RegionFunction -> regf]

enter image description here

$\endgroup$
0
$\begingroup$

Here is a version that uses only a single ContourPlot (I modified the predicates to be the same as kglr's):

s[foci_] := Sum[EuclideanDistance[{x,y},p], {p, foci}]

With[{foci = {{3, 2}, {5, 1}}, semimajoraxis = 1.7},
    ContourPlot[
        {
        ConditionalExpression[s[foci], x + 2 y - 5 >= 0] == 2 semimajoraxis,
        ConditionalExpression[s[foci], x + 2 y - 5 < 0] == 2 semimajoraxis
        },
        Evaluate[
            Sequence @@ MapThread[
                {#1, #2 - semimajoraxis, #2 + semimajoraxis} &,
                {{x, y}, Mean[foci]}
            ]
        ],
        RegionFunction -> Function[{x,y}, x+ y - 6<0],
        ContourStyle -> {Red, Blue}
    ]
]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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