5

I wish to add tick marks to facet plots. For instance, to a facet plot like this:

require(ggplot2)

p <- ggplot(mpg, aes(displ, hwy)) + 
     geom_point() + 
     theme_minimal() +
     geom_hline(yintercept=10, linetype="solid") +
     geom_vline(xintercept=1.0, linetype="solid") +
     scale_x_continuous(limits=c(1,8), expand =c(0,0), 
     breaks = rep(2:7)) +
     scale_y_continuous(limits = c(10, 50), expand = c(0,0), 
     breaks = c(20,30,40)) +
     facet_wrap(~cyl) +   
     theme(panel.margin.x=unit(1.2, "lines"),
     panel.margin.y=unit(1.2, "lines"))
p

enter image description here

I wish to add tick marks so that it could look like this (please note that although tick marks are added to all facets, tick labels are displayed only at the left and bottom facets):

enter image description here

I’ve tried using the annotation_custom function to add line grobs to the axis. However my attempts are not working.

require(gridExtra)
require(grid)   
x.breaks = rep(2:7)
y.breaks = c(20,30,40)

for (i in 1:length(x.breaks))   {
  p = p + annotation_custom(grob = linesGrob(y = unit(c(0, 5), "npc"),
                       gp=gpar(col= "black")),  
                       xmin = x.breaks[i], 
                       xmax = x.breaks[i], 
                       ymin = 8.69, 
                       ymax = 8.89)
  }

for (i in 1:length(y.breaks))   {
  p = p + annotation_custom(grob = linesGrob(x = unit(c(0, 5), "npc"),
                       gp=gpar(col= "black")),  
                       xmin = 0.769,
                       xmax = 0.809,                           
                       ymin = y.breaks[i], 
                       ymax = y.breaks[i])
  }

gt = ggplotGrob(p)
gt$layout$clip[gt$layout$name=="panel"] <- "off"
grid.draw(gt)

Does anyone have any suggestion? Thanks in advance.

R. Joe
  • 367
  • 5
  • 13

2 Answers2

5

Here's a low-level way of axing the numbers,

p <- ggplot(mpg, aes(displ, hwy)) + 
  geom_point() + 
  theme_bw() +
  geom_hline(yintercept=10, linetype="solid") +
  geom_vline(xintercept=1.0, linetype="solid") +
  scale_x_continuous(limits=c(1,8), expand =c(0,0), 
                     breaks = rep(2:7)) +
  scale_y_continuous(limits = c(10, 50), expand = c(0,0), 
                     breaks = c(20,30,40)) +
  facet_wrap(~cyl, scales="free") 

g <- ggplotGrob(p)
g$grobs$axis_b1$children[[2]][["grobs"]][[2]] <- nullGrob()
g$grobs$axis_b2$children[[2]][["grobs"]][[2]] <- nullGrob()
grid.newpage()
grid.draw(g)

enter image description here

one could also remove the corresponding space in the gtable.

baptiste
  • 75,767
  • 19
  • 198
  • 294
  • Thanks @baptiste. Your answer helped. Further adding: `g$grobs$axis_l2$children[[2]][["grobs"]][[1]] <- nullGrob()` and `g$grobs$axis_l4$children[[2]][["grobs"]][[1]] <- nullGrob()` Reproduced the plot I needed. If a future version of `ggplot2` can make available arguments in the `facet_wrap()` function to customize facet tick marks and facet tick labels, maybe this type of question can be solved more easily. – R. Joe Aug 17 '16 at 14:00
0

Here is a solution using grid.arrange function and grid package :

enter image description here

p_top = ggplot(subset(mpg, cyl %in% c(4,5)), aes(displ, hwy)) + 
     geom_point() + 
     theme_minimal() +
     geom_hline(yintercept=10, linetype="solid") +
     geom_vline(xintercept=1.0, linetype="solid") +
     scale_x_continuous(limits=c(1,8), expand =c(0,0), 
     breaks = rep(2:7)) +
     scale_y_continuous(limits = c(10, 50), expand = c(0,0), 
     breaks = c(20,30,40)) +
     facet_wrap(~cyl, ncol = 2) +
     theme(axis.ticks.x = element_line(), axis.text.x = element_blank()) + 
     labs(x=NULL, y = NULL)

p_bot = ggplot(subset(mpg, cyl %in% c(6,8)), aes(displ, hwy)) + 
     geom_point() + 
     theme_minimal() +
     geom_hline(yintercept=10, linetype="solid") +
     geom_vline(xintercept=1.0, linetype="solid") +
     scale_x_continuous(limits=c(1,8), expand =c(0,0), 
     breaks = rep(2:7)) +
     scale_y_continuous(limits = c(10, 50), expand = c(0,0), 
     breaks = c(20,30,40)) +
     facet_wrap(~cyl, ncol = 2) +
     theme(axis.ticks.x = element_line()) + 
     labs(y = NULL)

library(grid)
grid.arrange(p_top, p_bot, left = textGrob("hwy", rot = 90, vjust = 1))
bVa
  • 3,839
  • 1
  • 13
  • 22