Re: Suppressing display of LogPlots
- To: mathgroup at smc.vnet.net
- Subject: [mg22648] Re: [mg22568] Suppressing display of LogPlots
- From: Dan Warren <drdanw at my-deja.com>
- Date: Thu, 16 Mar 2000 09:11:06 -0500 (EST)
- References: <200003112252.RAA03265@smc.vnet.net> <8aj7gl$1ao$2@dragonfly.wolfram.com>
- Sender: owner-wri-mathgroup at wolfram.com
In clairifying the problem for Usenet posting, the application was reduced to triviality. You are, of course, correct that the simple solution of Show[g2,DisplayFunction->$DisplayFunction] displays the plot. However, the reason I used the Block in the first place was so I wouldn't have to explicitly set the DisplayFunction option when I want to see the plot outside the Block. In the original application, I have a utility function which generates a list of Graphics objects, some of which were logarithmic plots. A simple example: In[24]:= g = Block[{$DisplayFunction = Identity}, {Plot[Sin[x], {x, Pi, 3*Pi}], LogLinearPlot[Sin[x], {x, Pi, 3*Pi}]}] Out[24]= {-Graphics-, -Graphics-} returns a list of two graphics objects, with no display. Later, I want to see my plots by mapping Show over the list: In[25]:= Show /@ g -------- Only the first plot displays. ------------ Out[25]= {-Graphics-, -Graphics-} This is very unexpected behavior, to Show a list of two graphics and only see one plot. Of course, I could map a the function: Show[#,DisplayFunction->$DisplayFunction]& /@ g but this is more typing than I want to do on a regular basis, plus it requires the user to remember that LogPlots do not behave the same as Plots. My hack allows me to isolate the fix to the function which generates the graphics and spare the user the details. The problem arises because the value of a local variable leaks out of the scoping function through a sneaky side-effect. Within the Block, $DisplayFunction = Identity. LogLinearPlot calls ScaledPlot with the default option DisplayFunction :> $DisplayFunction (notice the RuleDelayed.) Now, ScaledPlot needs to manipulate the options, so it saves some of the options it was passed, including disp = DisplayFunction /. opts; Later, ScaledPlot is supposed to restore the original options by prepending DisplayFunction -> disp to the option sequence. The problem is that the option is not restored to its original value (DisplayFunction :> $DisplayFunction) but is replaced by a Rule to the value $DisplayFunction had when the disp = line was evaluated, that is, DisplayFunction -> Identity. This circumvents the RuleDelayed mechanism and allows the local value (Identity) to leak out of the Block. In article <8aj7gl$1ao$2 at dragonfly.wolfram.com>, Hartmut Wolf <hwolf at debis.com> wrote: > Dr Dan schrieb: > > > > There is a programming oversight (er, bug) in the Graphics` package > > that interferes with the delayed evaluation of DisplayFunction > > options. A common trick to suppress the display of graphics is to wrap > > Plot in a Block function: > > > > In[1]:= > > Block[{$DisplayFunction = Identity}, > > g1 = Plot[Sin[x], {x, 0, 3*Pi}]; ]; > > > > In[2]:= > > Show[g1] > > > > ---------plot deleted > > Out[2]= > > -Graphics- > > > > However, this trick does not work for many plot types defined in the > > Graphics`Graphics` package: > > > > In[3]:= > > << "Graphics`Graphics`" > > > > In[4]:= > > Block[{$DisplayFunction = Identity}, > > g2 = LogLinearPlot[Sin[x], {x, 0, 3*Pi}]; ]; > > > > In[5]:= > > Show[g2] > > > > ------------- plot doesn't show! > > Out[5]= > > -Graphics- > > > > We can see why the plot does not display outside the Block by checking > > the DisplayFunction options in the graphic: > > > > In[6]:= > > Options[g2, DisplayFunction] > > > > Out[6]= > > {DisplayFunction -> Identity, DisplayFunction :> Identity} > > > > I have tracked this bug to the utility functions ScaledPlot and > > ScaledListPlot in Graphics.m. Since I am not brave enough to attempt > > to fix the code, I created the following hack: > > > > DisplayFunctionHack[Graphics[args__, > > (opts___)?OptionQ]] := Graphics[args, > > {Flatten[{DisplayFunction :> $DisplayFunction, > > DeleteCases[Flatten[{opts}], (Rule | RuleDelayed)[ > > DisplayFunction, _]]}]}] > > > > The DeleteCases is not strictly necessary, but I like to clean up. We > > can see the effect of the hack by checking the options of the graphic > > again: > > > > In[8]:= > > g3 = DisplayFunctionHack[g2]; > > > > In[9]:= > > Options[g3, DisplayFunction] > > > > Out[9]= > > {DisplayFunction :> $DisplayFunction} > > > > Now the graphics displays properly: > > > > In[10]:= > > Show[g3] > > > > ----------------graphic deleted, but trust me, it was here. > > Out[10]= > > -Graphics- > > > > Sent via Deja.com http://www.deja.com/ > > Before you buy. > > Dr. Dan, > > if I do > > In[7]:= Show[g2, DisplayFunction -> $DisplayFunction] > > -- Graphics deleted, was there -- > > Out[7]= Graphics[] > > I see the plot, so where's the bug? > > Block gives you the guarantee that the plot operations inside wouldn't > show, nothing else! If $DisplayFunction -- the current "default display > function" -- is explicitly referenced inside the Block as part of a > definition, the referenced value will prevail, e.g. inside of g2. > > Of course you can reset this immediately: > > In[10]:= > g2 = Block[{$DisplayFunction = Identity}, > LogLinearPlot[Sin[x], {x, 0, 3*Pi}]] /. > {(DisplayFunction -> Identity) -> (DisplayFunction -> > $DisplayFunction)} > Out[10]= Graphics[] > > In[11]:= Show[g2] > > -- Graphics deleted, was there -- > > Out[11]= Graphics[] > > Hartmut > > Sent via Deja.com http://www.deja.com/ Before you buy.
- Follow-Ups:
- Re: Re: Suppressing display of LogPlots
- From: Hartmut Wolf <hwolf@debis.com>
- Re: Re: Suppressing display of LogPlots
- References:
- Suppressing display of LogPlots
- From: Dr Dan <drdanw@my-deja.com>
- Suppressing display of LogPlots