Search code examples
rggplot2gridextra

Grid.arrange with zero margins / Mirrored barplots without spacing


I am trying to connect two ggplot barplots which are mirrored. I wanted to use grid.arrange to join the two individual plots at the axis. Unfortunately, I always have a space between the plots. How can I reduce the margin completely so that both plots are joined on a single axis?

Thats what i have tried so far:

DWP1 <- data.frame("City" = c("Berlin", "Paris", "London"),
                   "People" = c(3.3, 2.1, 9))
DWP2 <- data.frame("City" = c("New York", "Washington", "Miami"),
                  "People" = c(8.4, 0.7, 0.4))

PR <- ggplot(DWP1, aes(x = reorder(City, People), y = People,reorder(City,-People)))+
  theme(axis.line = element_line(),
        panel.background = element_rect(fill = "transparent", color = NA),
        plot.background = element_rect(fill= "transparent", color = NA),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.border = element_blank(),
        legend.position = "none",
        axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank(),
        axis.line.x=element_blank(),
  )+
  geom_col(aes(fill = City), width = 0.1, position =  position_dodge(-0.9), linetype="dotted")+
  xlab("")+
  coord_flip()+
  theme(axis.title.y = element_text(angle = 0, size=0, vjust = 0.5, family= Schriftart, color="black"))+
  scale_y_continuous(expand = expansion(mult = c(0, .1)))

PL <- ggplot(DWP2, aes(x = reorder(City, People), y = People,reorder(City,-People)))+
  theme(axis.line = element_line(),
        panel.background = element_rect(fill = "transparent", color = NA),
        plot.background = element_rect(fill= "transparent", color = NA),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.border = element_blank(),
        legend.position = "none",
        axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank(),
        axis.line.x=element_blank(),
        axis.line.y=element_blank(),
  )+
  geom_col(aes(fill = City), width = 0.1)+
  xlab("")+
  coord_flip()+
  scale_y_continuous(expand = expansion(mult = c(0, .1))) +
  scale_y_reverse()

PL + PR

Here is a picture of how it currently looks. Both plots should merge completely.

enter image description here

At the end both plots should be united in PlotLR: PlotLR <- PlotL + PlotR

I am grateful for any hint!


Solution

  • This could be achieved like so. As you want almost all theme elements removed you could simply make use of theme_void() and instead of removing add desired theme elements like the y-axis. Additionally I removed the legends via guide(fill="none") and set the plot margins equal to zero. Finally I added the axis line for the right plot and reversed the expansion for the left plot:

    DWP1 <- data.frame("City" = c("Berlin", "Paris", "London"),
                       "People" = c(3.3, 2.1, 9))
    DWP2 <- data.frame("City" = c("New York", "Washington", "Miami"),
                       "People" = c(8.4, 0.7, 0.4))
    
    library(ggplot2)
    
    PR <- ggplot(DWP1, aes(x = reorder(City, People), y = People,reorder(City,-People)))+
      theme_void() +
      geom_col(aes(fill = City), width = 0.1, position =  position_dodge(-0.9), linetype="dotted")+
      coord_flip() +
      scale_y_continuous(expand = expansion(mult = c(0, .1))) +
      theme(axis.line.y = element_line(), plot.margin = unit(rep(0, 4), "pt")) +
      guides(fill = "none")
    
    PL <- ggplot(DWP2, aes(x = reorder(City, People), y = People,reorder(City,-People)))+
      theme_void() +
      geom_col(aes(fill = City), width = 0.1)+
      coord_flip()+
      scale_y_reverse(expand = expansion(mult = c(.1, 0))) +
      theme(plot.margin = unit(rep(0, 4), "pt")) +
      guides(fill = "none")
    
    library(patchwork)
    
    PL + PR
    

    library(gridExtra)
    
    grid.arrange(PL, PR, nrow = 1)