MathGroup Archive 2000

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

Search the Archive

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.


  • Prev by Date: Re: Question
  • Next by Date: running a program in batch
  • Previous by thread: Re: Suppressing display of LogPlots
  • Next by thread: Re: Re: Suppressing display of LogPlots