Search code examples
rplotggplot2graphfacet-grid

`ggplot2 - facet_grid`: Axes without ticks in interior facets


I would like to create facet_grid / facet_wrap plot with the x axis being repeated under each graph but with ticks present only on the lowest graph.

Here is an example of a plot with the x axis present only once using facet_grid

ggplot(mtcars, aes(y=mpg,x=cyl)) + 
  facet_grid(am~., scales="free") + 
  geom_point() + 
  theme_classic() + 
  theme(strip.background = element_rect(colour="white", fill="white"),
        strip.text.y = element_blank())

enter image description here

Here is an example of a plot with the x axis present twice but with ticks both times using facet_wrap

ggplot(mtcars, aes(y=mpg, x=cyl)) + 
  facet_wrap(~am, ncol=1, scales="free") + 
  geom_point() + 
  theme_classic() + 
  theme(strip.background = element_rect(colour="white", fill="white"),
        strip.text.x = element_blank())

enter image description here

I would like the same plot as the one just above but without the ticks on the x-axis of the upper graph. Or if you prefer, I would like the same plot as the first one but with an x-axis on the upper graph.


Solution

  • This is a very verbose solution, but I don't think you can get the plot you want using just the usual ggplot functions.

    library(ggplot2)
    library(grid)
    
    Plot <- ggplot(mtcars, aes(y=mpg, x=cyl)) + 
      facet_wrap(~am, ncol=1, scales="free") + 
      geom_point() + 
      theme_classic() + 
      theme(strip.background = element_rect(colour="white", fill="white"),
            strip.text.x = element_blank())
    

    Switching off the top x-axis requires modifying the gtable object for the plot.

    Plot.build <- ggplot_gtable(ggplot_build(Plot))
    axis.pos <- grep("axis-b-1-1", Plot.build$layout$name)
    num.ticks <- length(Plot.build$grobs[[axis.pos]]$children[2]$axis$grobs[[1]]$y)
    

    This step removes the axis labels:

    Plot.build$grobs[[axis.pos]]$children$axis$grobs[[2]]$children[[1]]$label <- rep("", num.ticks)
    

    This step removes the tick marks:

    Plot.build$grobs[[axes.pos]]$children[2]$axis$grobs[[1]]$y <- rep(unit(0, units="cm"), num.ticks)
    

    Finally, the plot is generated using:

    grid.draw(Plot.build)
    

    enter image description here