MathGroup Archive 2000

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

Search the Archive

Re: Re: Suppressing display of LogPlots

  • To: mathgroup at smc.vnet.net
  • Subject: [mg22679] Re: [mg22648] Re: [mg22568] Suppressing display of LogPlots
  • From: Hartmut Wolf <hwolf at debis.com>
  • Date: Sat, 18 Mar 2000 01:27:53 -0500 (EST)
  • Organization: debis Systemhaus
  • References: <200003112252.RAA03265@smc.vnet.net> <8aj7gl$1ao$2@dragonfly.wolfram.com> <200003161411.JAA10257@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

Hallo Dan,

after your last clarification, let me add a short comment (if it becomes
boring just click it away).


Dan Warren schrieb:
> 
> 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, .....

Yes, surprising. In such a case you might use

In[]:= Show[GraphicsArray[g]]
  -- all graphics will display here --
Out[]= GraphicsArray[]

However, in fact, you have shown the limits of that well popularized
ideom
Block[{$DisplayFunction=Identity}, -some plotting procedure-] where
(within some perhaps unknown and unaccessible procedure) we want the
current display function to do nothing when it comes to execute it, but
have it's original value (as outside of Block) transferred where it is
referenced. Such stated, this is an unreachable goal. If you are going
to write a plotting procedure yourself you may carefully control the
execution, as Allan Hayes has shown. But we want to build on the work of
others.

To fix the problem one has to make some assumption. The assumption here
is that the should be surviving reference to $DisplayFunction is only in
the options of the resulting graphical objects. (That of course is a
very senseful assumption, but you easily can write a procedure that
violates it -- and still is not nonsensical.) You defined

> > >
> > > DisplayFunctionHack[Graphics[args__,
> > > (opts___)?OptionQ]] := Graphics[args,
> > > {Flatten[{DisplayFunction :> $DisplayFunction,
> > > DeleteCases[Flatten[{opts}], (Rule | RuleDelayed)[
> > > DisplayFunction, _]]}]}]
> > >

and achieved your goal, as not to 
> 
>    ... 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.
> 

In my opinion you were perfectly right 

> > >                                ... not ... to attempt
> > > to fix the code, I created the following ...

The suggestion I made was not to post-process the received graphics, but
do that while they are being created. My now improved version is

<< "Graphics`Graphics`"

Attributes[dontdisplay] = {HoldAll};

dontdisplay[plotting_]:= Block[{$DisplayFunction = Identity}, plotting ]
/. 
{opt_[DisplayFunction, _]?OptionQ :> opt[DisplayFunction,
$DisplayFunction]}

g = {g2, g1} = {LogLinearPlot[Sin[x], {x, 0, 3*Pi}], 
        Plot[Sin[x], {x, 0, 2 Pi}]} // dontdisplay
Out[]=
{Graphics[], Graphics[]}

Show /@ g
 -- both graphics had been displayed here --
Out[]= 
{Graphics[], Graphics[]}

Having defined this function everything is graceful and at ease.


In my last contribution to this thread I gave you a puzzle:
> 
> In[24]:= Block[{$DisplayFunction},
>   g2x = LogLinearPlot[Sin[x], {x, 0, 3*Pi}]; ]
> 
> In[25]:= g2x
>  -- believe it or not, Graphics was here --
> Out[25]= Graphics[]
> 
and
> 
> In[27]:= g2 === g2x
>  -- again, Graphics was here (once only!) --
> Out[27]= True
> 

You may exploit that behaviour when proceeding like that:

In[12]:= Block[{$DisplayFunction}, 
  g2z = Identity@@LogLinearPlot[Sin[x], {x, 0, 3*Pi}]]

Out[12]= Graphics[]

In[13]:= Show[g2z]
 -- graphics was here --
Out[13]= Graphics[]

In[14]:= Cases[g2z, _[DisplayFunction, _], Infinity]
Out[14]=
{DisplayFunction -> (Display[$Display, #1] & ), 
  DisplayFunction :> Identity}

Now you see Block makes $DisplayFunction undefined (and as such it can't
execute) but all references to it will be kept intact. Finally, after
having built the graphics object when the plotting function passes the
object to $DisplayFunction _that_ occurance will be replaced by
Identity.

To make this to a general "minimal invasive method" for suppressing
display you first have to check the assumption, _different_ from that
one above, that all plotting routines show there object through that
final call to $DisplayFunction.

I havn't done this yet.

Kind regards,  Hartmut


  • Prev by Date: Re: cubic polynomial
  • Next by Date: Re: cubic polynomial
  • Previous by thread: Re: Suppressing display of LogPlots
  • Next by thread: Re: Suppressing display of LogPlots