Plotting in a loop in Mathematica

January 20th, 2010 | Categories: mathematica, programming | Tags:

Ever since version 6 of Mathematica was released (way back in 2007) I have received dozens of queries from users at my University saying something along the lines of ‘Plotting no longer works in Mathematica’ or ‘If I wrap my plot in a Do loop then I get no output.  The user usually goes on to say that it worked perfectly well in pre-v6 versions of Mathematica, is clearly a bug and could I please file a bug report with Wolfram Research?

It’s not a bug….it’s a feature!

If you have googled your way here and just want a fast solution to your problem then here goes.  I assume that you have code that looks like this

Do[
Plot[Cos[n x], {x, -Pi, Pi}]
, {n, 1, 3}
]

and you were expecting to get a set of nice plots (in this case 3) – one plot for each iteration of your loop. Instead, Mathematica 6 or above is giving you nothing…nada…zip! There are several ways you can ‘fix’ this and I am going to show you two. Option 1 is to wrap your Plot Command with Print

Do[
Print[Plot[Cos[n x], {x, -Pi, Pi}]]
, {n, 1, 3}
]

Option 2 is to use Table instead of Do

Table[
Plot[Cos[n x], {x, -Pi, Pi}]
, {n, 1, 3}
]

I am imaging that the average googler has now disappeared having got what they came for but some of you are possibly wondering why the above two ‘fixes’ work.  Here’s my attempt at an explanation.

Old versions of Mathematica (v5.2 and below) treated graphics very differently to the way that Mathematica works today. The output of a command such as Plot[] used to contain two parts – the first was a Graphics object which looked a bit like the following in the notebook front end

– Graphics –

This was the OutputForm of the actual symbolic result of the Plot[] command. The second part – the actual visualization of the plot – was effectively just a side effect that happened to be what us humans actually wanted.

In version 6 and above, the OutputForm of a Graphics object is its visualisation which makes a lot more sense then just – Graphics –. The practical upshot of this is that there is now no need for a ‘side effect’ since the visualization of the plot IS the output.  If you are confused then this bit is explained much more eloquently in an old Wolfram Blog post.

That’s the first part of the story regarding plots in loops.  The second piece of the puzzle is to know that when you wrap a Mathematica expression in a Do loop then you suppress its output but you don’t suppress any side effects.  In version 5.2 the plot is a side effect and so it gets displayed on each iteration of the loop.  In version 6 and above, the plot is the output and so gets suppressed unless you explicitly ask for it to be displayed using Print[].

Does this help clear things up?  Comments welcomed.

1. For[i = 0, i < 5, Plot[Cos[x], {x, -Pi, Pi}], i++]

This similarly suppresses output. This is definitely a good thing.

"Notice that all of the symbolic information necessary to describe an image lurks not far behind the image itself. That makes it possible in Mathematica 6 to define functions that grab an image’s symbolic description, rearrange or otherwise modify the description, and instantly update the image. Hook that function up to a button and put the button into a notebook, and you have the beginnings of a palette that operates on graphics"

Sweet!

2. Hi Joshua

I agree – the new behaviour is definitely the right way to go since it allows you to do some very cool stuff. It confuses old time users though – hence this post :)

Best Wishes,
Mike

3. I have noticed that it’s very beneficial to take the time to understand the meaning of that blog post. Most people assume that they don’t care, but if you’re doing anything but the most basic drawing, you will quickly care. The thing is that in the new system, Do doesn’t really suppress output at all. It may sound easier to describe it this way, but that’s missing out on some good stuff. Here’s what’s happening:

Plot is a symbol that *returns* a Graphics object. I emphasize “returns” because it’s important later.

As you know, every line in a notebook (Mathematica notebook, not a laptop) is considered an “input”. By default, when you input something to the kernel, it wants to give you corresponding output.

So there are two questions: (1) how to locate the value to output and (2) how to output it.

The answer to (1) is that Mathematica will Evaluate[] and then output the Left Hand Side of every input (after any assignment is done; if there’s no assignment, the expression itself is the LHS).

The answer to (2) is that it basically calls Print on the result from (1). It’s a little more complicated than that, but sufficed to say that in this case the notebook knows to match output to the input, and that’s where the In[xx] and Out[xx] messages come from.

To suppress the output, put a “;” character at the end of the line.

x=y (*prints y as output*)
x=z; (*does the assignment, but prints nothing*)
x (*prints z as output*)

Now when you call Print yourself, you are also creating output but it’s not matched by the notebook to any particular input, so there is no corresponding Out[xx] prompt.

x=z (*prints Evaluate[x], which is z*)
x=z;Print[x]; (*basically the same thing, but without the info to match this output to the line of input*)
x=z;Print[Evaluate[x]]; (*even more explicit, although the Evaluate is not needed because it’s implicit in Print*)

So a basic plot:

Plot[Cos[x], {x, -Pi, Pi}]

is really doing this:
1) Call the function Plot
2) Plot returns a Graphics object
3) This object is the LHS of the expression, so the kernel wants to output it
4) Call Print on the object to output it

For example:
Plot[Cos[x], {x, -Pi, Pi}]; (*suppress output, no plot*)
g=Plot[Cos[x], {x, -Pi, Pi}] (*assigns the object to g, then outputs g because it is the LHS*)
Print[g] (*outputs g again, minus the Out[xx] prompt*)

Now Do results in no printing because… Do does not return a value. No return value means no printing:
1) Evaluate the Do
2) Nothing is returned
3) No return means no output

Table, however, does this:
1) Evaluate the Table function
2) Table returns a List of graphics objects
3) Need to output a List
4) Lists are output like this: Print the brackets, iterate the list and Print each element, make sure to Print commas between elements

And why is this so useful to know? Now we know that Table is really returning a List of Graphics objects, we can do interesting things:

g = Table[Plot[Cos[n x], {x, -Pi, Pi}], {n, 1, 3}]; (* assign the list to g, suppress output *)
g (* send the list to output *)
Print[g] (*same thing, minus Out[xx]*)
Show[g] (*overlay all elements of the list together*)
p=Show[g]; (*overlay all elements of g to a new Graphics object, assign the object to p*)

We can do all kinds of fun things with these graphics objects. Other than overlaying them, we can reuse and modify them as described in that blog post.

4. Good posts, both Mike and Hans! I would add to Hans’s post, though, that Evaluate is a symbol intended to be used to selectively override the attributes HoldFirst, HoldRest, or HoldAll (note not HoldComplete or HoldAllComplete) and does not really “evaluate” anything in any sense beyond this; it just becomes Identity in other situations.

Hopefully the new Mathematica 6 or 7 users are happy with the change… I for one do not miss having to write something of the form:
Show[
{Graphics[{…},DisplayFunction->Identity],
Plot[…,DisplayFunction->Identity],
…},
DisplayFunction->\$DisplayFunction
]

5. Oh, I forgot to mention: if you aren’t inclined to change your code in a particular instance and don’t use any New in 6 graphics primitives, then you can Get[“Version5Graphics”] to use the old PostScript-based renderer. This can be useful if you have written some fairly complicated code to produce the graphics. Unfortunately the speed of the version 6 and 7 front ends can’t match that of version 5.2–for comparison, version 7 can produce 100 plots using the PostScript renderer in just over 5 seconds, whereas version 5.2 manages it in 0.2 seconds. For this and other reasons, I have always kept my older versions of Mathematica around even after I’ve migrated to using a newer version on a day-to-day basis.

6. Hi Ben

Regarding

Get[“Version5Graphics”]

I have a gut feeling that you have just solved a long-standing problem for an academic here! Something that has prevented him from updating to version 6 and 7 for quite some time. I’ll investigate and blog about it if my gut feeling turns out to be true.

Thanks and best wishes,
Mike

7. Glad to hear that my comment might have helped someone. Incidentally, as far as I’m able to tell through some brief experimentation, PostScript graphics output interacts somewhat oddly with Panel and other interface elements and may not work correctly inside Dynamic. However, if your user has never used version 6 or 7, I doubt this will matter very much to him.

He might, however, be bothered by the fact that once Version5Graphics has been loaded one then needs to use the old-style Graphics options (e.g. PlotJoined rather than Joined) and the Front End does not recognise these, colouring them red when entered. On the other hand, this issue also shows up regularly if you supply undocumented or custom options, and one can always disable or change the colouring of unrecognised options if necessary. I personally think that syntax colouring was perhaps the most broadly useful front end development in version 6, and I suspect that he will agree with me on this point.

8. How to do the loop of expresion list in Mathematica ? Reading tutorials, I understood that it is not possible to do similar as in Pascal or C, ie
do i=1 to ik
expr1
expr2
expres3
end

?