Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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"}] 
share|improve this question
    
Its the Evaluate that is forcing the early resolution of x. –  Ymareth Jul 28 at 15:55
    
Try wrapping the Plot command with Block[{x},....]. –  kale Jul 28 at 15:58
1  
For this reason it is better to use the option Evaluated -> True instead of Evaluate –  Simon Woods Jul 28 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 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 at 16:08

2 Answers 2

up vote -1 down vote accepted

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

share|improve this answer
    
Can you expand a bit ? It is too vague ... –  Sektor Jul 28 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 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]

enter image description here

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}]
]
share|improve this answer
    
Thank you Mr. Wizard for the detailed explaination! –  lychee Jul 28 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 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 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 at 22:03

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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