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
- References:
- Suppressing display of LogPlots
- From: Dr Dan <drdanw@my-deja.com>
- Re: Suppressing display of LogPlots
- From: Dan Warren <drdanw@my-deja.com>
- Suppressing display of LogPlots