Re: RuleDelayed plot options and Show

*To*: mathgroup at smc.vnet.net*Subject*: [mg77845] Re: RuleDelayed plot options and Show*From*: Szabolcs <szhorvat at gmail.com>*Date*: Mon, 18 Jun 2007 06:57:22 -0400 (EDT)*Organization*: University of Bergen*References*: <23637841.1181983021122.JavaMail.root@m35> <f531ba$1t9$1@smc.vnet.net>

DrMajorBob wrote: > On Sat, 16 Jun 2007 03:00:24 -0500, zac <replicatorzed at gmail.com> 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"}; Show[ GraphicsArray[ Table[ 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 > Szabolcs