Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Looking at this question, I am reminded of a problem that I was never able to solve with obtaining a particular plot format.

The issue is that GridLines sit behind anything in Prolog. You can have gridlines with a colored background by giving the background a non-zero Opacity.

Framed@Plot[Sin[x], {x, 0, 2 \[Pi]}, Frame -> True, 
  Prolog -> {LightGray, Opacity[0.5], 
    Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]}, 
  GridLines -> {None, Automatic}]

enter image description here

But if the gridlines are to be white, this isn't feasible, it seems.

Framed@Plot[Sin[x], {x, 0, 2 \[Pi]}, Frame -> True, 
  Prolog -> {LightGray, Opacity[0.5], 
    Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]}, 
  GridLines -> {None, Automatic}, 
  GridLinesStyle -> Directive[AbsoluteThickness[2], White]]

enter image description here

Yes, you can use the undocumented option Method -> {"GridLinesInFront" -> True}, as described in this answer, but then the gridlines go on top of the plot line as well as the background.

Framed@Plot[Sin[x], {x, 0, 2 \[Pi]}, Frame -> True, 
  Prolog -> {LightGray, Opacity[0.5], 
    Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]}, 
  GridLines -> {None, Automatic}, 
  GridLinesStyle -> Directive[AbsoluteThickness[2], White], 
  Method -> {"GridLinesInFront" -> True}]

enter image description here

Is there a way to reorder the Prolog background or the gridlines somehow, so that white gridlines shock, but the gridlines don't go over the plotted function?

Try as I might I was never able to replicate this format (the axis numbers inside the frame are a whole other question).

enter image description here

share|improve this question
    
Please see my edits. The inability to resize overlays has always been bugging me. It turns out it is possible. –  Szabolcs Feb 24 '12 at 21:35
    
Now in V10 GridLinesInFront is documented in Graphics –  Murta Jul 10 at 16:54
add comment

3 Answers 3

up vote 9 down vote accepted

Slightly hackish, but you could use Epilog to get the curve on top of the grid, e.g.

pl = Plot[Sin[x], {x, 0, 2 Pi}][[1]];

Plot[ Sin[x], {x, 0, 2 Pi}, 
 PlotStyle -> None, Frame -> True,
 Method -> {"GridLinesInFront" -> True}, 
 GridLines -> Automatic, 
 GridLinesStyle -> Directive[AbsoluteThickness[2], White],
 Prolog -> {{LightGray, Opacity[0.5], Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]}},
 Epilog -> pl]

Mathematica graphics

Edit

Following Mr.Wizard's and Szabolcs' suggestions, an more elegant solution would be:

plot = Plot[Sin[x], {x, 0, 2 Pi}, 
    Frame -> True, GridLines -> Automatic,
    GridLinesStyle -> Directive[AbsoluteThickness[2], White]];

Graphics[{}, Method -> {"GridLinesInFront" -> True},
 Epilog -> plot[[1]], 
 Prolog -> {{LightGray, Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]}}, 
 Sequence @@ Options[plot]]

This has the advantage that the plot is only generated once. It should work for any plot that doesn't have any Prolog's or Epilog's of itself.

You can even build it into a nice custom function:

myPlot[x_, range_List, opts : OptionsPattern[]] := 
 With[{plot = 
    Plot[x, range, Frame -> True, GridLines -> Automatic, 
     GridLinesStyle -> Directive[AbsoluteThickness[2], White], 
     opts]},
  Graphics[{}, Method -> {"GridLinesInFront" -> True}, 
   Epilog -> plot[[1]], 
   Prolog -> {{LightGray, Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]}},
    Sequence @@ Options[plot] ] ]

myPlot[Cos[x], {x, 0, 2 Pi}, PlotStyle -> Red]

enter image description here

Or an extended version:

myPlot[x_, type_, range_List, opts : OptionsPattern[]] := 
 With[{plot = 
    Switch[type, Plot, 
     type[x, range, Frame -> True, GridLines -> Automatic, 
      GridLinesStyle -> Directive[AbsoluteThickness[2], White], 
      opts],
     ParametricPlot, 
     type[x, range, Frame -> True, GridLines -> Automatic, 
      GridLinesStyle -> Directive[AbsoluteThickness[2], White], 
      opts],
     ListPlot, 
     type[x, PlotRange -> range, Frame -> True, 
      GridLines -> Automatic, 
      GridLinesStyle -> Directive[AbsoluteThickness[2], White], 
      opts],
     ListLinePlot, 
     type[x, PlotRange -> range, Frame -> True, 
      GridLines -> Automatic, 
      GridLinesStyle -> Directive[AbsoluteThickness[2], White], opts]
     ]},
  Graphics[{}, Method -> {"GridLinesInFront" -> True}, 
   Epilog -> plot[[1]], 
   Prolog -> {{LightGray, Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]}},
    Sequence @@ Options[plot] ] ]

myPlot[RandomVariate[NormalDistribution[], 
  100], ListLinePlot, {Automatic, Full}, PlotStyle -> Red]

enter image description here

share|improve this answer
    
Why am I not surprised? +1 :-) –  Mr.Wizard Feb 24 '12 at 21:26
1  
Very nice, +1. With ideas from all three answers, how about Graphics[{}, Method -> {"GridLinesInFront" -> True}, GridLines -> Automatic, GridLinesStyle -> White, Epilog -> plot[[1]], Prolog -> {{LightGray, Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]}}, Sequence @@ Options[plot] ] ? This ought to work for any plot that does not have a Prolog or Epilog or grid lines and it does not double graphics. –  Szabolcs Feb 24 '12 at 21:41
    
@Mr.Wizard my only (minor) gripe with your solution is that it plots two curves on top of each other (which is why I used PlotStyle -> None in pl2), but @Szabolcs solution would solve that. –  Heike Feb 24 '12 at 21:50
1  
@Mr.Wizard I've already edited my solution. –  Heike Feb 24 '12 at 21:58
    
Is there a reason why you defined a plotting function instead of a function which takes any graphics object and lifts the content above the grid lines while shading the background? –  Szabolcs Feb 26 '12 at 0:45
add comment

This is non-ideal for so many reasons, but (at least in the front end) it does what you describe:

plot = Plot[Sin[x], {x, 0, 2 Pi}, Frame -> True]

Overlay[{
  Graphics[{}, Sequence @@ Options[plot], 
   Method -> {"GridLinesInFront" -> True}, 
   GridLines -> Automatic, 
   GridLinesStyle -> White, 
   Prolog -> {LightGray, Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]}
   ],
  Show[plot, FrameStyle -> Opacity[0]]
}]

Mathematica graphics

When it comes to exporting / copying / resizing, it becomes increasingly inconvenient though. I think I would generate my own grid lines just to avoid having to deal with a non-Graphics object.

EDIT:

Here's a hack to at least let you resize it interactively:

Pane[
 Overlay[{
   Graphics[{}, Sequence @@ Options[plot],
    Method -> {"GridLinesInFront" -> True},
    GridLines -> Automatic,
    GridLinesStyle -> White, 
    Prolog -> {LightGray, Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]},
    ImageSize -> Full],
   Show[plot, FrameStyle -> Opacity[0], ImageSize -> Full]
   }],
 ImageSize -> Large,
 AppearanceElements -> {"ResizeArea"}
]

EDIT 2:

Better resizing. Just don't right click -> Save As ... It'll save only one graphic.

DynamicModule[{sz = Medium},
 Overlay[{
   Graphics[{}, Sequence @@ Options[plot],
    Method -> {"GridLinesInFront" -> True},
    GridLines -> Automatic,
    GridLinesStyle -> White, 
    Prolog -> {LightGray, Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]},
    ImageSize -> Dynamic[sz]],
   Show[plot, FrameStyle -> Opacity[0], ImageSize -> Dynamic[sz]]
   }, All, 2]
 ]
share|improve this answer
add comment

Why not draw the gridlines in Prolog too?

Module[{origplot,
       xglst = Range[0, 5 Pi/4, Pi/8], 
       yglst = Range[-1, 1, 1/5],
       xpglst, ypglst, gridlines,
       xrm, xrM, yrm, yrM, paddingTable, pl, pr, pb, pt},
       origplot = Plot[Sin[x], {x, 0, 5 Pi/4},
                       PlotStyle -> Thickness[.005],
                       Frame -> True, FrameTicks -> {xglst, yglst, {}, {}},
                       Prolog -> {GrayLevel[.9], Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]}
                      ];
       {{xrm, xrM}, {yrm, yrM}} = PlotRange /. AbsoluteOptions[origplot, PlotRange];
       paddingTable = PlotRangePadding /. AbsoluteOptions[origplot, PlotRangePadding] /. Scaled -> Identity;
       {{pl, pr}, {pb, pt}} = If[Head[#] === List, #, {#, #}] & /@ paddingTable;
       xpglst = pl + (1 - pl - pr) (xglst - xrm)/(xrM - xrm);
       ypglst = pb + (1 - pb - pt) (yglst - yrm)/(yrM - yrm);
       gridlines = {Thickness[.01], White,
                    Line[{Scaled[{#, 0}], Scaled[{#, 1}]}] & /@ xpglst,
                    Line[{Scaled[{0, #}], Scaled[{1, #}]}] & /@ ypglst};
       origplot /. (Prolog -> expr_) :> (Prolog -> Join[expr, gridlines])
      ]

which will give

enter image description here

The key point is calculating Scaled position of the gridlines from PlotRange and PlotRangePadding.

btw. I noticed that the format of FrameTicks described in Help, which is {{left,right},{bottom,top}}, will cause the AbsoluteOptions alarming, while a format as {bottom, left, top, right} will work fine. Wondering is this a bug? (maybe I should ask in a sole question?)

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.