R. Joe
R. Joe

Reputation: 377

Add tick marks to facet plots in R

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.

Upvotes: 5

Views: 2376

Answers (2)

baptiste
baptiste

Reputation: 77096

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.

Upvotes: 5

bVa
bVa

Reputation: 3938

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))

Upvotes: 0

Related Questions