# why the variable scope is not local when using evaluate to plot multicurve?

I noticed a surprising problem when using evaluate to plot multicurve, "evaluate" function actually consider global variable first, not the local! I can illustrate the problem using the following simple example, say I want to plot multicurve Z=1*x^2, 3*x^2, 5*x^2, 7*x^2 using a two-variate function Z[x_,y_]:=y*x^2, the following will work:

Z[x_, y_] := y*x^2;
Needs["PlotLegends"];
Plot[Evaluate[Table[Z[x, y], {y, 1, 7, 2}]], {x, 1, 5}, PlotRange -> All,
PlotStyle-> {Purple, Red, Green, Blue},
PlotLegend -> Table[Style[SequenceForm["y=", y], Bold, 16], {y, 1, 7, 2}],
AxesLabel -> {"x", "Z"}]


But inserting a global variable (say x=1) before the plot command will over ride the local variable used for the plot range ({x,1,5} in the example). So Instead of plotting Z=1*x^2, 3*x^2, 5*x^2, 7*x^2, it will plot Z=1*1^2, 3*1^2, 5*1^2, 7*1^2. Isn't this counter-intuitive?

I think the ListPlot is more intuitive in terms of variable scope. Because the following implementation using ListPlot is not interfered by global variable x.

ListPlot[Table[Table[{x, Z[x, y]}, {x, 1, 5, 0.1}], {y, 1, 7, 2}],
PlotRange -> All, PlotStyle -> {Purple, Red, Green, Blue}, Joined -> True,
PlotLegend -> Table[Style[SequenceForm["y=", y], Bold, 16], {y, 1, 7, 2}],
AxesLabel -> {"x", "Z"}]

-
Its the Evaluate that is forcing the early resolution of x. –  Ymareth Jul 28 '14 at 15:55
Try wrapping the Plot command with Block[{x},....]. –  kale Jul 28 '14 at 15:58
For this reason it is better to use the option Evaluated -> True instead of Evaluate –  Simon Woods Jul 28 '14 at 15:58
To Simon Woods: Thanks for mentioning the "option" approach, unfortunately it will interfere with showing the PlotLegend: only one curve is shown in the legend if I use the option approach. Any further suggestions? Thanks. –  lychee Jul 28 '14 at 16:06
Sure, wrap it up with Block[] or Module[] will work, just need to know this problem in priori :) Thanks to Ymareth and kale. –  lychee Jul 28 '14 at 16:08

You can localize x using...Module[{x}, Plot[Evaluate[Table[Z[x,y]...

-
Can you expand a bit ? It is too vague ... –  Sektor Jul 28 '14 at 16:22
I think Mr Wizard has done a better job that I can in the time available (though I could have done better than the one liner!). –  Ymareth Jul 30 '14 at 13:15

Evaluate specifically operates to force evaluation:

Evaluate[expr] causes expr to be evaluated even if it appears as the argument of a function whose attributes specify that it should be held unevaluated.

You can use Evaluate to override HoldFirst, etc. attributes of built-in functions.

Evaluate only overrides HoldFirst, etc. attributes when it appears directly as the head of the function argument that would otherwise be held.

Plot has the Attribute HoldAll so that resolution of global assignments does not take place preemptively, but you are overriding that behavior.

The simplest workaround is to use the undocumented option Evaluated -> True which I prefer(1),(2),(3),(4) specifically because it does respect scoping:

x = "Fail!";

Plot[Sinc[x*Range[3]], {x, -5, 5}, Evaluated -> True]


If you prefer not to use undocumented functionality you can use Block, as Plot likely does internally:

Block[{x},
Plot[Sinc[x*Range[3]] // Evaluate, {x, -5, 5}]
]
`
-
Thank you Mr. Wizard for the detailed explaination! –  lychee Jul 28 '14 at 18:27
@lychee You're welcome, but I can't help noticing you Accepted the other answer instead. May I know why? –  Mr.Wizard Jul 28 '14 at 18:30
I could only accept one answer. So first come, first serve. I would accept both if I could. BTW, you have soooooo many points :) –  lychee Jul 28 '14 at 19:12
@lychee That's your prerogative. Please don't take my inquiry as coercion. It's not about the points these days, not that it every really was, but helping people. In this case I was a little surprised and disappointed because I don't feel that Ymareth ever answered your question: he never explained why the variable was not localized. Further I felt if it came down to solutions rather than answering the question that I had the better one. I still do. That's my prerogative. :^) –  Mr.Wizard Jul 28 '14 at 22:03