Home > Software design >  Align x-axis in two plots using ggplot2 or patchwork
Align x-axis in two plots using ggplot2 or patchwork

Time:11-11

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

CodePudding user response:

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()`).

CodePudding user response:

The issue is that your Gains variable contains only missings for Site 67, whereas the value of Discharge is 0 for this Site. Hence, Site 67 gets from the barchart dropped and you end up with a slightly differing range for the x scale. To fix that you could set the limits for the x scale to range(data$Site) or rev(range(data$Site)) as you use scale_x_reverse for both plots:

library(ggplot2)
library(patchwork)

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, limits = rev(range(data$Site)))  
  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), limits = rev(range(data$Site)))  
  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))

enter image description here

  • Related