MathGroup Archive 2007

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: RuleDelayed plot options and Show

DrMajorBob wrote:
> On Sat, 16 Jun 2007 03:00:24 -0500, zac <replicatorzed at> wrote:
>> Dear Group,
>> evaluate code to see error message:
>> SetOptions[Plot, AxesLabel :> {"X", y[[i]]}];
>> y = {"Y1", "Y2"};
>> Show[
>>     GraphicsArray[
>>       Table[
>>         Plot[Sin[x], {x, -1, 1}]
>>         , {i, 2}]
>>       ]
>>     ];
>> The problem is Show does not know what iterator 'i' means. The
>> individual plots have the correct y axis labels, but Show failes to
>> print them in the array (since in Show the y labels are re-evaluated -
>> due to RuleDelayed).
 > The index in your AxesLabel has to be global, since it can't be a
 > local
 > variable peculiar to Table, which after all (I think) has a different
 > internal name each time the Table is executed.

[Note: I changed the order of the two quoted posts to make this message 
more readable.]

First I would like to add a correction:  Table (and other functions 
which use iterators) do not rename the iteration variable, they just 
temporarily remove its value.  In other words, they do not function like 
Module[], but like Block[].

The reason why István's example does not work is that AxesLabel is 
stored as an option in Graphics; it is not expanded to a Text[] 
primitive. AxesLabel is used when the Graphics[] are displayed, not when 
Plot[] is evaluated.

Let us use a simpler example:

SetOptions[Plot, PlotLabel :> k];
Table[Plot[Sin[x], {x,0,10}], {k, 3}]

We get three plots; all have the label "k".

This is what happens:

Table[] evaluates the Plot function while k has the value 1 (or 2 or 3).
The result is a Graphics[] object which has the option PlotLabel :> k.
RuleDelayed (:>) holds its second argument, so k remains unevaluated.
The graphics are displayed only when Table[] has finished and k has lost 
its local value, so all three labels are "k".

However, if we use Rule instead of RuleDelayed, k will be evaluated 
while it still has a local value ...

SetOptions[Plot, PlotLabel -> k];
Table[Plot[Sin[x], {x,0,10}], {k, 3}]

... and the resulting Graphics[] objects will contain the options 
PlotLabel -> 1 (or 2 or 3). Correspondingly the labels will be "1" and 
"2" and "3".

But István's example requires the use of RuleDelayed.  What we can do is 
to force the "expansion" of the PlotLabel while k still has its local value:

SetOptions[Plot, PlotLabel :> k];
Table[FullGraphics@Plot[Sin[x], {x,0,10}], {k, 3}]

Of course it is not a good idea to set permanent options that only work 
in special circumstances, so the best solution is not to use SetOptions 
at all:

y = {"Y1", "Y2"};
        Plot[Sin[x], {x, -1, 1}, AxesLabel -> {"X", y[[i]]}],
        {i, 2}]

 > SetOptions[Plot, AxesLabel :> {"X", y[[k]]}];
 > y = {"Y1", "Y2"};
 > Show[GraphicsArray[Table[k = i; Plot[Sin[x], {x, -1, 1}], {i, 2}]]]

Here the problem is that the result of Plot[] will still contain 
AxesLabel :> {"X", y[[k]]}, because k is not evaluated in RuleDelayed.

When the graphics are displayed, k will have the value 2, so both plots 
will have the label "Y2".

 > Bobby


  • Prev by Date: Re: is there a better way to iterate this?
  • Next by Date: v6 GraphicsGrid with PlotLabel
  • Previous by thread: Re: RuleDelayed plot options and Show
  • Next by thread: REgarding grid point superposition