RE: GridPlot

• To: mathgroup at smc.vnet.net
• Subject: [mg45869] RE: [mg45795] GridPlot
• From: "Wolf, Hartmut" <Hartmut.Wolf at t-systems.com>
• Date: Wed, 28 Jan 2004 05:19:06 -0500 (EST)
• Sender: owner-wri-mathgroup at wolfram.com

>-----Original Message-----
>From: Selwyn Hollis [mailto:sh2.7183 at misspelled.erthlink.net]
To: mathgroup at smc.vnet.net
>Sent: Sunday, January 25, 2004 9:05 AM
>To: mathgroup at smc.vnet.net
>Subject: [mg45869] [mg45795] GridPlot
>
>
>I've never much liked the way the GridLines option works in Plot. So
>for my own amusement I decided to try something different, and it
>turned into a nice exercise, I think. I thought some of you might be
>interested in the result, which is the following (rough)
>function named
>GridPlot. What it basically does is stretch automatically-generated
>tickmarks out to form grid lines. (The GridColor option lets you can
>change their color.)
>
>
>GridPlot[f_, {x_, xmin_, xmax_}, opts___] :=
>  Module[{a, b, c, d, grph, fullgrph, gridcolor},
>    	gridcolor = GridColor /. {opts} /.
>		{GridColor -> GrayLevel[0.85]};
>     fullgrph = FullGraphics[grph = Plot[f, {x, xmin, xmax},
>		DisplayFunction -> Identity,
>		Evaluate[DeleteCases[{opts},GridColor->_]]]];
>     {{a, b}, {c, d}} = PlotRange /. AbsoluteOptions[grph];
>     Show[ fullgrph /.{
>	  {GrayLevel[0.], AbsoluteThickness[t_],
>		 Line[{{u_,y1_},{u_,y2_}}]}/; (y2-y1<d-c) ->
>        {gridcolor, AbsoluteThickness[t], Line[{{u,c},{u,d}}]},
>	  {GrayLevel[0.], AbsoluteThickness[t_],
>		Line[{{x1_,y_},{x2_,y_}}]}/; (x2-x1<b-a) ->
>         {gridcolor, AbsoluteThickness[t], Line[{{a,y},{b,y}}]}
>			},
>        grph, PlotRange -> {{a,b},{c,d}}, Axes -> True] ]
>
>GridPlot[{1/x, Cos[x], Sin[x]}, {x, 0, 2Pi}]
>
>
>
>Regards,
>-----
>Selwyn Hollis
>http://www.math.armstrong.edu/faculty/hollis
>

Selwyn,

as you declare this as a programming exercise I'm free to make comments and
to propose an alternative.

First, I agree that the Plot options in general, and for the GridLines in
particular are not easy to master.  If this constitutes a problem for the
(not so experienced) users of your code, your students e.g., it appears
appropriate to supply a more convenient interface.

My own private attitude is different however: try to understand -- albeight
this might cost some effort -- the basics (as is part of core Mathematica)
precisely.  This avoids irritations if something goes wrong: I then simply
have one interface _less_ to struggle with. The point may be simply
illustrated by

GridPlot[{1/x, Cos[x], Sin[x]}, {x, 0, 2Pi}, AspectRatio -> Automatic]

against

Plot[{1/x, Cos[x], Sin[x]}, {x, 0, 2Pi}, AspectRatio -> Automatic,
GridLines -> ({Thread[{Range[.2, 6.4, .2], xStyle}],
Thread[{Range[-1., 4., .2], yStyle}]} /. {xStyle |
yStyle -> {GrayLevel[.85]}})]

I would not say that the GridLines option was overly complex (but might need
some trial and error).

As you see, your proposed GridPlot looses the option AspectRatio, e.g. There
are other minor points of passing the options, which you can read off my
alternative example (coming below soon). Obviously you had to struggle to
get at the Ticks to make your gridlines from. The solution appears to be
delicate. Drawing the gridlines as primitives (instead of options to Show)
forces you to draw the graphics twice (which redundantly blows up the
Graphics objects). Finally everything is dedicated to Plot.

Here I propose a different solution, namely wrapper code which is thought to
cooperate with more (all?) plot functions. I also define the default
coloring of the grid as a default option.

Needs["Utilities`FilterOptions`"]

Options[makeGrid] = {GridStyle -> GrayLevel[0.85]};

Attributes[makeGrid] = HoldAll;

makeGrid[plotfcn_[args__, opts___?OptionQ]] := Module[{grph, gridstyle},

gridstyle = Flatten[{GridStyle /. Flatten[{opts}] /.
Options[makeGrid]}];

grph =
Block[{\$DisplayFunction = Identity},
With[{plotopts = FilterOptions[plotfcn, opts]},
plotfcn[args, plotopts]]];

Show[grph,
GridLines ->
Take[If[Frame /. Options[grph, Frame], FrameTicks, Ticks] /.
FullOptions[grph], 2] /. {pos_, _, _, _} :> {pos, gridstyle},
FilterOptions[Graphics, opts]]]

As you see, I extract the grid positions from the FrameTicks or Ticks via
the standard (stable?) interface. I also allow to specify more than one
graphical directive for the grid lines.

Examples of usage:

Needs["Graphics`Graphics`"]

Plot[{1/x, Cos[x], Sin[x]}, {x, 0, 2Pi},
GridStyle -> {Hue[0, .2, 1], Thickness[.01]},
AspectRatio -> Automatic] // makeGrid

pp = LogLogPlot[Exp[2x/Pi + Sin[x]], {x, 0., 6}] // makeGrid

PolarPlot[{4/(2 + Cos[t]), 4 Cos[t] - 2}, {t, 0, 2 Pi},
AspectRatio -> Automatic, Frame -> True,
PlotStyle -> {Hue[2/3], Hue[0]}] // makeGrid

So you just add the new GridStyle option to the other plotting options  and
wrap with makeGrid.

A warning in place: this is just a coding example, *not* released production
code. It should be put into a package first, then its should defend against
misuse (with not a plot function), and this must be done in a way as not to
point of weakness is the grabbing of the frame ticks. I simply take them
from the bottom and the left; but there might be none there. It's however
not difficult to solve this ("I leave it as an exercise"), and similar
cases. Then you must go through extensive testing, of course -- but I will
not do this work, that is beyond a post to the newsgroup.

Perhaps the best way would be to incorporate this into the
Graphics`Graphics` package (which then also would supply the necessary
extension for Plot), and leave the function makeGrid invisible to the user
(everthing would be directed by the option then). However, this should be
released from WRI, I myself would never do that, in order to keep my code
compatible with the "mainstream".

Kind regards, yours,
Hartmut

• Follow-Ups:
• Prev by Date: Re: Noisy data and ListConvolve
• Next by Date: NonlinearFit not reaching convergence, even after spoon-feeding it with initial parameters.
• Previous by thread: Re: GridPlot
• Next by thread: Re: RE: GridPlot