36

I am embarrassed to ask this simple question, but has been in kicking my mind for several days whenever I create a plot:

plot (x = 1:10, y = rnorm (10, 5, 2))
grid (10,10, lty = 6, col = "cornsilk2")

I want to position the grids right at where axis are labelled, i.e. at 2, 4, 6, 8, 10 in x axis and similarly 3, 4, 5, 6, 7, 8 in y axis.

enter image description here

I want to automate the process as whenever the plot size changes the default label behaviour changes. See the following plot:

enter image description here

zx8754
  • 52,746
  • 12
  • 114
  • 209
jon
  • 11,186
  • 19
  • 80
  • 132

4 Answers4

45

From ?grid description of the nx and ny arguments:

When NULL, as per default, the grid aligns with the tick marks on the corresponding default axis (i.e., tickmarks as computed by axTicks)

plot (x = 1:10, y = rnorm (10, 5, 2)) 
grid (NULL,NULL, lty = 6, col = "cornsilk2") 
jon
  • 11,186
  • 19
  • 80
  • 132
joran
  • 169,992
  • 32
  • 429
  • 468
  • +1 for explaining the help files and -1 for myself for not understanding the help well... – jon Nov 10 '11 at 15:46
  • 1
    This does not seem to work with timestamps on X axis. Any ideas? – slovon Nov 21 '17 at 14:08
  • 1
    @slovon I think you'll have to draw the grid manually in that case. The docs for `grid` say only that it will align with the ticks for the "default" axis, and clearly the datetime plot method is doing something different than what would be returned by `axTicks`. – joran Nov 21 '17 at 15:33
  • @slovon If it helps, I think the tick mark locations are coming from `graphics:::axis.POSIXct`. – joran Nov 21 '17 at 15:42
  • @slovon you should check this other question answer: https://stackoverflow.com/questions/42010161/align-grid-to-plot-ticks The `abline()` workaround works fine with time series objects. – AlejandroDGR Jul 13 '22 at 17:18
24

For reference, there is a way to control the grid and axes parameters directly from the plot() command, if we are not defining a custom tick interval:

plot(x = 1:10, y = rnorm(10, 5, 2), xlim=c(1, 10), ylim=c(1, 10), panel.first=grid())

The plot.default() documentation gives more information about these parameters.

When using a custom ticks interval, the easiest is to draw the grid using abline:

plot(x = 1:10, y = rnorm(10, 5, 2), xaxp=c(1, 10, 10), yaxp=c(1, 10, 10), axes=FALSE)
axis(1, 1:10)
axis(2, 1:10)
abline(h=1:10, v=1:10, col="gray", lty=3)

grid example

More information about custom tick intervals in this thread and here for grid alignment.

Community
  • 1
  • 1
Robert Kubrick
  • 8,413
  • 13
  • 59
  • 91
7

For posterity, here is the long-winded way of doing it manually:

plot (x = 1:10, y = rnorm (10, 5, 2))
grid (lty = 6, col = "cornsilk2")

xaxp <- par("xaxp")
yaxp <- par("yaxp")

abline(v=seq(xaxp[1], xaxp[2], (xaxp[2]-xaxp[1])/xaxp[3]), lty=6, col = "cornsilk2")
abline(h=seq(yaxp[1], yaxp[2], (yaxp[2]-yaxp[1])/yaxp[3]), lty=6, col = "cornsilk2")
Andrie
  • 176,377
  • 47
  • 447
  • 496
1

The answer provided here is much more straightforward, although you may dislike the lack of "free space" at each end of the axes. In brief,

The problem is that grid is putting nx grid lines in the user space, but plot is adding 4% extra space on each side. You can take control of this. Adding xaxs="i", yaxs="i" to your plot will turn off the extra space. But then your upper right point will be cut off, so you need to change the xlim and ylim values and change nx to match

Carl Witthoft
  • 20,573
  • 9
  • 43
  • 73