6

Currently I have a plot of a complicated function with gridlines turned on. Is there a way to shade a checkerboard pattern of alternating colors between adjacent grid cells?

So far, I have tried passing a table of rectangles into Prolog. However, I couldn't figure out how to pass in the max/min dimensions of the plot. Moreover, this approach is ugly and cumbersome, especially if I later want to modify the location of the gridlines.

Even better, I would like to shade a custom repeating pattern, specifically the following one:

0 | 0
-----
1 | 0

where 1 denotes {Pink, Opacity[0.1]} and 0 denotes a white background.

pre-kidney
  • 693
  • 3
  • 9

1 Answers1

8

You could make a checkerboard with Mesh funtionality in ParametricPlot:

mesh =
 ParametricPlot[{v, u}, {u, -2, 6}, {v, 0, 20},
  MeshFunctions -> {#2 &, #1 &}, 
  MeshShading -> {{RGBColor[1, 0.9, 0.9], White}, {White, White}},
  Mesh -> {8, 20},
  BoundaryStyle -> None
 ]

enter image description here

Then set it as a background with Prolog:

Plot[5 Sinc[x], {x, 0, 20},
  PlotRange -> All,
  PlotStyle -> {Red, Thick},
  Prolog -> mesh[[1]]
]

enter image description here

This method is quite flexible as you have specific control over the MeshFunctions etc. For example with MeshFunctions -> {Log[Abs@#2] &, Sinc[#1] &} you get:

enter image description here


Automation

The method above as a function for ease of application.

Options[addCheckerboard] =
  {MeshFunctions -> {#1 &, #2 &}, 
   MeshShading   -> {{RGBColor[1, 0.9, 0.9], White}, {White, White}},
   BoundaryStyle -> None};

addCheckerboard[gr_Graphics, opts : OptionsPattern[ParametricPlot]] :=
 {⌊#⌋, ⌈#2⌉} & @@@ PlotRange[gr] /. {{x_, X_}, {y_, Y_}} :>
   Show[gr,
    Prolog ->
     ParametricPlot[{u, v}, {u, x, X}, {v, y, Y},
       opts,
       Mesh -> ({X - x, Y - y} - 1),
       Evaluate @ Options @ addCheckerboard
     ][[1]]
   ]

You should now be able to apply this to any Graphics object as follows:

plot =
  Plot[Evaluate[Table[n^2*BesselJ[n, x], {n, 4}]], {x, 0, 10},
   AspectRatio -> Automatic];

addCheckerboard[plot]

enter image description here

(AspectRatio -> Automatic is included in the example but not necessary for functionality.)

  • You can change the fill color with MeshShading and the grid color with MeshStyle.
  • You can override the regular grid with different MeshFunctions as above.
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • Thank you. I would like to use this in the situation where the x range is known, but the y range is determined based on the range of the function. In other words, the range of u in the parametric plot is unknown (as well as the first argument of Mesh -> {8, 20}). Would there be an easy modification to accomplish this? – pre-kidney Jan 28 '15 at 18:36
  • There is one more issue. I need the gridlines to be placed at precisely the integers. It looks like yours are not - they are stretched to fit the range you have specified. – pre-kidney Jan 28 '15 at 18:39
  • @pre-kidney by the way I simply have to ask: what's with the name? :^) – Mr.Wizard Jan 28 '15 at 22:32
  • @pre-kidney Please see the update. – Mr.Wizard Jan 28 '15 at 23:55
  • This is wonderful! But the code is a bit mysterious to me and I'm trying to learn what it's doing. Would there be a way to run it all in a single Plot command, without having to reference the plot and look up its properties using PlotRange[gr]? Essentially, I would like to do this inline without having to reference the plot later. – pre-kidney Jan 29 '15 at 09:41
  • @pre-kidney I would be happy to try to explain any part you find opaque. I don't believe this can all be done inside Plot and still have the range detected automatically. Just in case you don't realize: you can use it like addCheckerboard[Plot[Tan[x], {x, -2, 2}]] without defining plot, but I don't think that's what you mean. By the way I just fixed a bug. – Mr.Wizard Jan 29 '15 at 10:14
  • @pre-kidney I also just realized that my implementation of the size parameter doesn't work. I'll have to change that a bit too. – Mr.Wizard Jan 29 '15 at 10:16