1
$\begingroup$

I am using ContourPlot to plot implicit equations. Plotting separate implicit equations seems to work fine, however I can't get ContourPlot to plot a piecewise function that returns implicit equations.

ClearAll["Global`*"];
a[p1_,p2_]:=(p1-30)^2+(2p2-60)^2==250
b[p1_,p2_]:=(p1-20)^2+(5p2-40)^2==300
pw[p1_,p2_]:=Piecewise[{{a[p1,p2],p1<p2}},b[p1,p2]]
Grid[{{
  ContourPlot[Evaluate@a[p1,p2],{p1,0,50},{p2,0,50}],
  ContourPlot[Evaluate@b[p1,p2],{p1,0,50},{p2,0,50}],
  ContourPlot[Evaluate@pw[p1,p2],{p1,0,50},{p2,0,50}]
}}]

Output

I am expecting the third figure to have 2 diagonal cut-off circles, like so: Expected output

$\endgroup$
1
  • $\begingroup$ Use RegionFunction for a workaround: Show[ ContourPlot[Evaluate@a[p1, p2], {p1, 0, 50}, {p2, 0, 50}, RegionFunction -> (#1 < #2 &)], ContourPlot[Evaluate@b[p1, p2], {p1, 0, 50}, {p2, 0, 50}, RegionFunction -> (#1 >= #2 &)]] $\endgroup$
    – Bob Hanlon
    Jan 6 '20 at 23:37
4
$\begingroup$

Try these two changes. First, use Boole instead of Piecewise, maybe like this

pw[p1_, p2_] :=  With[{b = Boole[p1 < p2]}, 
    (p1 - 20 - 10 b)^2 + (5 p2 - 40 - (3 p2 + 20) b)^2 == 300 - 50 b
]

Second, use pw[p1,p2] (without the underscores) in the ContourPlot command.

enter image description here

$\endgroup$
1
  • 1
    $\begingroup$ Thanks for picking up the underscore typo, I've edited the question. Interesting workaround, I wonder why Boole works and Piecewise does not? $\endgroup$
    – John Smith
    Jan 5 '20 at 22:56
2
$\begingroup$

ContourPlot works on an equation u == w by comparing values of u and w (or possibly by comparing u - w and 0, but it is equivalent). Further it relies on the continuity of u and w for its recursive subdivision algorithm and interpolates their numerical values at the mesh points to construct the linear segments of the contour, but that's not really the issue here; however it points to why ContourPlot needs access to the numerical values of the two sides of the equation. Your pw is not of the form u == w (full form Equal[u, w]). It has the equations buried inside it and returns only a boolean value. ContourPlot does not look any deeper into the expression. The fix is to bring the Equal outside the Piecewise. Here is one way to do that, by replacing the Equal in a[] and b[] by Subtract.

a[p1_, p2_] := (p1 - 30)^2 + (2 p2 - 60)^2 == 250;
b[p1_, p2_] := (p1 - 20)^2 + (5 p2 - 40)^2 == 300;
pw[p1_, p2_] := Piecewise[
   {{Subtract @@ a[p1, p2], p1 < p2}}, 
   Subtract @@ b[p1, p2]]  == 0;
Grid[{{
   ContourPlot[Evaluate@a[p1, p2],  {p1, 0, 50}, {p2, 0, 50}], 
   ContourPlot[Evaluate@b[p1, p2],  {p1, 0, 50}, {p2, 0, 50}], 
   ContourPlot[Evaluate@pw[p1, p2], {p1, 0, 50}, {p2, 0, 50}]}}]

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.