Search code examples
rggplot2facet-grid

Add both margins to facet_grid but not the combination


I want to show both the right and the bottom margin, but not the combination of both. Is this possible with facet_grid?

library(ggplot2)

ggplot(mtcars, aes(x = hp, group = vs)) + 
  geom_density() + 
  facet_grid(am ~ vs, switch = "y", margins = TRUE) 

I tried to fix it by manually providing the factors to the margin argument but that doesn't help. Also, the R Documentation does not help me.

Current outcome

The current outcome

Desired outcome

The desired outcome


Solution

  • ggplot2 uses fixed idioms for naming key plot elements so we can use that deterministic condition to find the elements:

    library(ggplot2)
    
    ggplot(mtcars, aes(x = hp, group = vs)) + 
      geom_density() + 
      facet_grid(am ~ vs, switch = "y", margins = TRUE) -> gg
    

    Build the plot into a gtable object:

    gt <- ggplot_gtable(ggplot_build(gg))
    

    Get the table cell names:

    cells <- gt$layout$name
    

    Figure out which one is the bottom corner panel and axis:

    apply(
      apply(
        do.call(rbind, strsplit(grep("panel", cells, value=TRUE), "-"))[,2:3],
        2, as.integer), 
      2, max
    ) -> max_col_row
    
    bottom_right_panel <- paste0(c("panel", max_col_row), collapse="-")
    bottom_axis <- sprintf("axis-b-%s", max_col_row[2])
    

    Figure out which ones are not the bottom corner panel:

    paste0(
      grep(sprintf("^%s|%s$", bottom_corner, bottom_axis), cells, value=TRUE, invert = TRUE),
      collapse = "|"
    ) -> not_bottom_corner_panel
    

    Only draw those:

    grid::grid.draw(
      gtable::gtable_filter(gt, sprintf("^(%s)$", not_bottom_corner_panel))
    )