Search code examples
rggplot2facetpatchwork

Align x-axis in two plots using ggplot2 or patchwork


I am trying to align two plots, a line plot and bar plot, but the axis is slightly shifted. Can you recommend ways in ggplot2 or patchwork or other faceted plot package. Thanks

reproducible code

data<-data.frame(
  Gains=c(NA,18.26,27.7,13.09,-8.36,1.73,5.57,17.1,-31.31,5.43,38.97,18.81,6.12,1.85,NA,16.28,21.18,3.44,-0.14,-3.87,10.57,11.942,-2.12,-0.07,33.34,13.66,14.14,30.66,NA,17.7,24.286,14.638,-7.986,0.622,9.265,3.216,-30.509,4.714,37.78,17.842,11.606,12.188),
  Site=c(67,66,61,60,58,57,55,52,48,44,42,39,33,24.5,67,66,61,60,58,57,55,52,48,44,42,39,33,24.5,67,66,61,60,58,57,55,52,48,44,42,39,33,24.5),
  Discharge=c(0,18.26,52.16,65.25,56.89,58.62,64.4,81.5,50.19,55.62,94.59,129.37,146.87,154.17,0,16.28,43.09,46.53,46.39,42.52,53.3,65.242,39.46,39.39,72.73,98.21,112.35,143.01,0,17.7,49.266,63.904,55.918,57.67,67.155,78.255,47.746,52.46,90.24,125.092,141.84,162.68)
  )
a<-ggplot(data, aes(x=Site, y=Discharge,))+
  stat_summary(geom = "ribbon", fun.min = min, fun.max = max, alpha = 0.25) +
  stat_summary(geom = "linerange", fun.min = min, fun.max = max, alpha = 0.3) +  
  stat_summary(geom = "line", fun = mean, size=1.2) +
  geom_point(aes(y = Discharge)) +
  annotate("rect", xmin = 60, xmax = 57, ymin = -Inf, ymax = Inf,
           alpha = .08)+
  annotate("rect", xmin = 52, xmax = 44, ymin = -Inf, ymax = Inf,
           alpha = .08)+
  scale_y_continuous(n.breaks=10)+
  scale_x_reverse(n.breaks=10)+
  xlab("River Mile")+
  ylab("Discharge (cfs)")
   

b<-ggplot(data, aes(x=Site, y=Gains,))+
  stat_summary(geom = "bar", fun = mean)+
  #stat_summary(geom = "errorbar",fun.min = min, fun.max = max, alpha = 0.3)+
  annotate("rect", xmin = 60, xmax = 57, ymin = -Inf, ymax = Inf,
           alpha = .08)+
  annotate("rect", xmin = 52, xmax = 44, ymin = -Inf, ymax = Inf,
           alpha = .08)+
  scale_x_reverse(breaks=seq(20,80,5))+
  scale_y_continuous(breaks=seq(-30,50,10))+
  ylab("Gain and Loss (cfs)")+
  xlab("River Mile")
    
pwrk<- b/a
pwrk + plot_layout(heights = c(1,2))

result shows problem


Solution

  • You can add coord_cartesian(xlim=c(70,20)) to each plot and it will work. You can change the xlim-values as you want, as long as they are the same in both plots.

    library(ggplot2)
    library(patchwork)
    
    data<-data.frame(
      Gains=c(NA,18.26,27.7,13.09,-8.36,1.73,5.57,17.1,-31.31,5.43,38.97,18.81,6.12,1.85,NA,16.28,21.18,3.44,-0.14,-3.87,10.57,11.942,-2.12,-0.07,33.34,13.66,14.14,30.66,NA,17.7,24.286,14.638,-7.986,0.622,9.265,3.216,-30.509,4.714,37.78,17.842,11.606,12.188),
      Site=c(67,66,61,60,58,57,55,52,48,44,42,39,33,24.5,67,66,61,60,58,57,55,52,48,44,42,39,33,24.5,67,66,61,60,58,57,55,52,48,44,42,39,33,24.5),
      Discharge=c(0,18.26,52.16,65.25,56.89,58.62,64.4,81.5,50.19,55.62,94.59,129.37,146.87,154.17,0,16.28,43.09,46.53,46.39,42.52,53.3,65.242,39.46,39.39,72.73,98.21,112.35,143.01,0,17.7,49.266,63.904,55.918,57.67,67.155,78.255,47.746,52.46,90.24,125.092,141.84,162.68)
    )
    a<-ggplot(data, aes(x=Site, y=Discharge,))+
      stat_summary(geom = "ribbon", fun.min = min, fun.max = max, alpha = 0.25) +
      stat_summary(geom = "linerange", fun.min = min, fun.max = max, alpha = 0.3) +  
      stat_summary(geom = "line", fun = mean, size=1.2) +
      geom_point(aes(y = Discharge)) +
      annotate("rect", xmin = 60, xmax = 57, ymin = -Inf, ymax = Inf,
               alpha = .08)+
      annotate("rect", xmin = 52, xmax = 44, ymin = -Inf, ymax = Inf,
               alpha = .08)+
      scale_y_continuous(n.breaks=10)+
      scale_x_reverse(n.breaks=10)+
      xlab("River Mile")+
      ylab("Discharge (cfs)")+
      coord_cartesian(xlim=c(70,20))
    #> Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
    #> ℹ Please use `linewidth` instead.
    
    
    b<-ggplot(data, aes(x=Site, y=Gains,))+
      stat_summary(geom = "bar", fun = mean)+
      #stat_summary(geom = "errorbar",fun.min = min, fun.max = max, alpha = 0.3)+
      annotate("rect", xmin = 60, xmax = 57, ymin = -Inf, ymax = Inf,
               alpha = .08)+
      annotate("rect", xmin = 52, xmax = 44, ymin = -Inf, ymax = Inf,
               alpha = .08)+
      scale_x_reverse(breaks=seq(20,80,5))+
      scale_y_continuous(breaks=seq(-30,50,10))+
      ylab("Gain and Loss (cfs)")+
      xlab("River Mile") +
      coord_cartesian(xlim=c(70,20))
    
    pwrk<- b/a
    pwrk + plot_layout(heights = c(1,2))
    #> Warning: Removed 3 rows containing non-finite values (`stat_summary()`).