Plot draws list of curves in same color when not using Evaluate

92

34

This example comes from the Mathematica documentation for Plot under Basic Examples.

Can someone please explain why these are each plotted as a different color in this case:

Plot[Evaluate[Table[BesselJ[n, x], {n, 4}]], {x, 0, 10}, Filling -> Axis]

enter image description here

But when Evaluate[] is removed, all of them are the same color:

Plot[Table[BesselJ[n, x], {n, 4}], {x, 0, 10}, Filling -> Axis]

enter image description here

I know it must have to do with the order of things being evaluated, but I'm really not sure why it is working like this - can someone please point me in the correct direction?

trayres

Posted 2012-02-14T07:21:40.930

Reputation: 1 045

3Hmm... I'm almost positive I've seen this question asked here before, but I can't seem to find it... – David Z – 2012-02-14T07:26:36.710

4Yeah, this is very much an FAQ. – J. M.'s ennui – 2012-02-14T07:55:34.917

Answers

73

The list structure is not manifest to Plot as it has the attribute HoldAll (to get a function's attributes, either use Attributes[func] or ??func). Hence Plot evaluates the Table functions as one unit and it appears as if there is only one function, not four.

Evaluate will make the list structure manifest and each function will be plotted with a separate style.

Matariki

Posted 2012-02-14T07:21:40.930

Reputation: 3 162

6I apologize if this is naive question, but what does "The list structure is not manifest to Plot" mean? – brown.2179 – 2013-12-30T12:23:19.313

It means that Plot isn't seeing the argument as a list. A list is treated as one argument not many arguments as Plot has HoldAll attribute . – Matariki – 2013-12-31T22:06:54.627

if I use Evaluate[...] or Evaluated->True it takes forever to plot the functions, as compared without those. Is there any way to still assign different colors without losing the speed? – riddleculous – 2017-02-24T17:40:17.153

43

Mathematica 10 update

It seems that now Plot specifically recognizes Sequence which invalidates the example given below, but not its premise. If one uses a different head that behaves similarly the behavior is still exhibited:

Plot[{1, ## &[2, 3], 4}, {x, 0, 1}, PlotRange -> {0, 5}, PlotStyle -> Thick]

Or:

f[x__] := x

Plot[{1, f[2, 3], 4}, {x, 0, 1}, PlotRange -> {0, 5}, PlotStyle -> Thick]

Or:

Plot[{1, {2, 3} /. {x__} :> x, 4}, {x, 0, 1}, PlotRange -> {0, 5}, PlotStyle -> Thick]

Analysis

Plot builds style lists based on the apparent structure of the first argument it is given, before evaluation. List is recognized and elements are styled individually, while generic functions like Table are styled as a whole.

You can see this behavior here, where Sequence acts as a "generic head":

Plot[
  {1, Sequence[2, 3], 4}, {x, 0, 1},
  PlotRange -> {0, 5},
  PlotStyle -> Thick
]

Mathematica graphics

On the other hand sub-lists are recognized and styled:

Plot[
  {1, {2, 3}, 4}, {x, 0, 1},
  PlotRange -> {0, 5},
  PlotStyle -> Thick
]

Mathematica graphics

You can read my own question about this and Sasha's excellent answer (starting from EDIT 2).


Recommended form for evaluation

I recommend that you use the option Evaluated -> True rather than Evaluate as it (still) localizes the plot variable. See:

Mr.Wizard

Posted 2012-02-14T07:21:40.930

Reputation: 259 163

1

This is not working anymore in V10 :( I liked it, this however, works: 72929. They not how to handle Sequence but ## &[2, 3] will do! :)

– Kuba – 2015-01-31T07:18:20.610

@Kuba Thanks for the note; I hadn't yet noticed it. I'll update the answer. – Mr.Wizard – 2015-01-31T07:28:23.150

1To which V10 version does your Mathematica 10 update apply? With MMA V10.1 and Plot[{1, ## &[2, 3], 4}, {x, 0, 1}, PlotRange -> {0, 5}, PlotStyle -> Thick]' I get an error (Identity::argx: Identity called with 2 arguments; 1 argument is expected` – Sigis K – 2015-04-09T13:26:02.457

@SigisK That was for 10.0.2. Thanks for letting me know that the new form is broken too. When I get 10.1 I'll see what I can learn. – Mr.Wizard – 2015-04-09T14:45:21.507

@SigisK What about the other two methods shown in the Update section? – Mr.Wizard – 2015-04-09T14:47:28.253

The other two methods also get the same error. – Sigis K – 2015-04-09T17:21:37.017

@SigisK I am now using 10.1.0 under Windows and all three of the "Mathematica 10 update" methods work without error on my system. What operating system do you use? – Mr.Wizard – 2015-05-25T13:28:51.573

I am sorry to have misled you, I genuinely thought to have a 10.1 version: I was confused between $Version which returned 10.0 and $ReleaseNumber which returned 1 (and I concatenated these 2 to make 10.1) and I forgot to give a feedback . I upgraded now to 10.1 and these errors are gone but others are still present (please look at my latest question to which I gave my own answer since no answer was given after 4 months). – Sigis K – 2015-05-25T15:18:59.380

@SigisK I shall take a careful look at your Q&A later. (I am only briefly checking in a few times today.) I am sorry to see what appears to be a good Q&A fall through the cracks. For what it's worth a few of mine have too despite the presumed name recognition I have here. Please do not let it discourage you from posting. – Mr.Wizard – 2015-05-25T15:44:31.560

+1 for Evaluated -> True. Just solved my problem of long computation due to algebraic simplification of Plot's argument prior to each evaluation. – Casimir – 2017-06-07T15:10:43.107

@Casimir Happy to help. Be aware that in recent versions the Evaluated does not work with PlotLegends; see (69104)

– Mr.Wizard – 2017-06-08T00:03:18.313

13Clever trick to use Sequence[] to constrain a group to have the same color... :) – J. M.'s ennui – 2012-02-14T08:40:35.840

22

Evaluate evaluates your expression that you want to plot. This transforms the expression Table[BesselJ[n, x], {n, 4}] that you give as an argument into a list of several functions. If Plot sees several functions, it knows it can use more colors. Without Evaluate, Plot does not know you have several functions and uses only one color. That comes from the fact that Plot has the attribute HoldAll: it does not evaluate your arguments. Without evaluation the first time it sees, that several numbers are coming out of your function is during the plotting. Then it's too late to color it differently, and you get only a single colored plot.

halirutan

Posted 2012-02-14T07:21:40.930

Reputation: 109 574

9

Just to strengthen the idea that Plot does not evaluate the expression even with simplest operations

Plot[0 + {Sin[x], Cos[x]}, {x, 0, 2 π}, Filling -> Axis]

enter image description here

Algohi

Posted 2012-02-14T07:21:40.930

Reputation: 19 067

It took me 5 minutes to understand what you meant. It would be easier if you mentioned the the curves have the same color because of unevaluated expression – anhnha – 2019-11-26T04:04:38.773