# Defined equality does not show in ContourPlot

I have some function definitions that ultimately define an equality through Solve and Replace:

Curve[p_] := w1*x^p + w2*y^p; (* some function with parameters *)
ComputeWeights[p1_, p2_, p_] := (* compute w1 and w2 through Solve *)
Solve[w1 == 1 - w2 &&
w1*p1[[1]]^p + w2*p1[[2]]^p == w1*p2[[1]]^p + w2*p2[[2]]^p, {w1,
w2}][[1]];
MyCurve[p1_, p2_, p_] := Curve[p] /. ComputeWeights[p1, p2, p];
MyConstant[p1_, p2_, p_] :=
MyCurve[p1, p2, p] /. {x -> p1[[1]], y -> p1[[2]]};
MyEquality[p1_, p2_, p_] :=
MyCurve[p1, p2, p] == MyConstant[p1, p2, p];


Now, I can use the defined equality:

t1 = {0.2, 0.5}; t2 = {0.6, 0.3}; MyEquality[t1, t2, 10]


which correctly outputs

0.138326 x^10 + 0.861674 y^10 == 0.000841493


If I try to graph this with a ContourPlot, it works fine:

(* ok *) ContourPlot[0.138326 x^10 + 0.861674 y^10 == 0.000841493, {x, 0, 1}, {y, 0, 1}]


However, if I embed the MyEquality function in ContourPlot (which is the reason why I defined it in the first place) it no longer works (I see an empty square, but no curve):

(* ko *) ContourPlot[MyEquality[t1, t2, 10], {x, 0, 1}, {y, 0, 1}]


Strangely enough, it works if I use a function for the lhs of the equality:

(* ok *) ContourPlot[MyCurve[t1, t2, 10] == 0.000841493, {x, 0, 1}, {y, 0, 1}]


but not if I use a function for the rhs:

(* ko *) ContourPlot[0.138326 x^10 + 0.861674 y^10 == MyConstant[t1, t2, 10], {x, 0, 1}, {y, 0, 1}]


There must be something profound I don't understand about replacements and equalities (and possibly function definitions) in Mathematica. What is the problem here?

## 1 Answer

Wrap the first argument of ContourPlot with Evaluate:

ContourPlot[Evaluate@MyEquality[t1, t2, 10], {x, 0, 1}, {y, 0, 1}]


Notes:

ContourPlot (and all *Plot functions) have the Attribute HoldAll, that is, all arguments are maintained in an unevaluated form.

So, in a simpler example,

eqn = Cos[x] == Cos[y];
ContourPlot[eqn, {x, 0, 4 Pi}, {y, 0, 4 Pi}]


does not produce anything because ContourPlot sees eqn not Cos[x] == Cos[y]. Forcing evaluation of eqn by wrapping it with Evaluate,

 ContourPlot[Evaluate@eqn, {x, 0, 4 Pi}, {y, 0, 4 Pi}]


works as if we used

 ContourPlot[Cos[x] == Cos[y], {x, 0, 4 Pi}, {y, 0, 4 Pi}]

• Great, thanks! But what is it that prevents the resulting expression to be evaluated, i.e., why do I have to force evaluation? – Maiaux Nov 29 '18 at 17:43
• @Maiaux, ContourPlot (and all *Plot functions) have the Attribute HoldAll ( that is, all arguments to a function are maintained in an unevaluated form.) So, in a simpler example, eqn = Cos[x] == Cos[y]; ContourPlot[eqn, {x, 0, 4 Pi}, {y, 0, 4 Pi}] does not produce anything because ContourPlot sees eqn not Cos[x] == Cos[y]. Forcing evaluation of eqn by wrapping it with Evaluate, (ContourPlot[Evaluate@eqn, {x, 0, 4 Pi}, {y, 0, 4 Pi}]) works as if we used ContourPlot[Cos[x] == Cos[y], {x, 0, 4 Pi}, {y, 0, 4 Pi}]. Hope this helps. – kglr Nov 29 '18 at 18:23
• ... See also Evaluate in the docs. – kglr Nov 29 '18 at 18:23
• Thanks @kglr. However I now wonder why my third example works (and the last one doesn’t), even without forcing evaluation. After all, they both have some parts that need to be evaluated... – Maiaux Nov 29 '18 at 22:28
• @Maiaux, it is puzzling. I don't know the answer otomh. Maybe, if you have patience, Trace[ContourPlot[...]] with the two inputs might reveal something about the difference. – kglr Nov 29 '18 at 23:06