# 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?

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? Commented Nov 29, 2018 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
Commented Nov 29, 2018 at 18:23
• ... See also Evaluate in the docs.
– kglr
Commented Nov 29, 2018 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... Commented Nov 29, 2018 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
Commented Nov 29, 2018 at 23:06