r - Overlay grid rather than draw on top of it

ID : 274356

viewed : 30

Tags : rggplot2r

Top 4 Answer for r - Overlay grid rather than draw on top of it

vote vote


ggplot introduced an option in theme() that lets you do just that with pull number 993, on June 18, 2015.

Just add to your plot:

+ theme(   panel.background = element_rect(fill = NA),   panel.ontop = TRUE ) 

There is an example in the ggplot docs.

vote vote


You could use grid package functionality to extract the grid lines from the plot, and then redraw them, which would avoid some of the manual specification when adding horizontal or vertical lines.

library(ggplot2) library(grid)  # Draw your plot ggplot(data.frame(x=sample(1:100),y=sample(1:100)), aes(x=x,y=y))+    geom_point(size=20)  # This extracts the panel including major and minor gridlines lines <- grid.get("grill.gTree", grep=TRUE)  # Redraw plot without the gridlines # This is done, as otherwise when the lines are added again they look thicker last_plot() +    theme(panel.grid.minor = element_blank(),         panel.grid.major = element_blank())  # Navigate to relevant viewport # To see these use grid.ls(viewports=TRUE) seekViewport("panel.3-4-3-4")  # Redraw lines grid.draw(lines$children[-1]) 

Which produces

enter image description here

Alternatively, if you wanted to automate the adding of the vertical and horizontal lines within ggplot (as in Narendra's answer), but without specifying the breaks manually, you can access their positions using ggplot_build(p), where p is your plot.

It may be worth showing this for a graph with facets. Same procedure, except you select multiple lines and panels, and then just loop through them to draw.

# New plot with facets ggplot(mtcars, aes(mpg, wt)) + geom_point(size=10) + facet_grid(am~cyl)  gr <- grid.ls(print=FALSE) # Get the gTree for each of the panels, as before     lines <- lapply(gr$name[grep("grill.gTree", gr$name)], grid.get)  last_plot() +    theme(panel.grid.minor = element_blank(),         panel.grid.major = element_blank())  # Get the names from each of the panels panels <- gr$name[grep("panel.\\d", gr$name)]  # Loop through the panels redrawing the gridlines for(i in 1:length(panels)) {              seekViewport(panels[i])              grid.draw(lines[[i]]$children[-1])              } 

This will also work for the plots without facts.

vote vote


Here's a workaround using geom_hline and geom_vline.

f <- ggplot(mpg, aes(cty, hwy)) f + geom_smooth(color="red") 

It generates this plot.

enter image description here

To add horizontal and vertical lines manually:

f + geom_smooth(color="red")    + geom_vline(xintercept = c(10,15,20,25,30,35), color="white", size=1.25)    + geom_hline(yintercept = c(20,30,40), color="white", size=1.25) 

To automatically add xintercept and yintercept:

f <- ggplot(mpg, aes(cty, hwy)) + geom_smooth(color="red") x_intercept <- ggplot_build(f)$panel$ranges[[1]]$x.major_source ## x_intercept ## [1] 10 15 20 25 30 35 y_intercept <- ggplot_build(f)$panel$ranges[[1]]$y.major_source ## y_intercept ## [1] 20 30 40 f + geom_vline(xintercept=x_intercept, color="white", size=1.25)   + geom_hline(yintercept=y_intercept, color="white", size=1.25) 

Now any changes in axis-ticks introduced by scale-* functions will reflect in the final plot.
Here we have horizontal and vertical lines (similar to grid) on top of the plot. You can vary size to make lines more thick. enter image description here

But it's just a workaround. Given the flexibility of ggplot2 package, I think something similar can be achieved using theme. But I do not know how.

Edit1 : We can try following but it won't put grids on top. This way we can change size, color, linetype but that's all.

f + geom_smooth(color="red")    + theme(panel.grid.major=element_line(color="white", size=2)) 

Edit2 : Added automatically insertion of xintercept and yintercept using ggplot_build(f) as explained here.

vote vote


Top 3 video Explaining r - Overlay grid rather than draw on top of it