使用ggplot将条形图的列与线图的点对齐

Line up columns of bar graph with points of line plot with ggplot

有什么方法可以使用 ggplot 将线图的点与条形图的条对齐,当它们具有相同的 x 轴时?这是我尝试使用的示例数据。

library(ggplot2)
library(gridExtra)

data=data.frame(x=rep(1:27, each=5), y = rep(1:5, times = 27))
yes <- ggplot(data, aes(x = x, y = y))
yes <- yes + geom_point() + geom_line()

other_data = data.frame(x = 1:27, y = 50:76  )

no <- ggplot(other_data, aes(x=x, y=y))
no <- no + geom_bar(stat = "identity")

grid.arrange(no, yes)

这是输出:

线图的第一个点在第一个柱的左侧,线图的最后一个点在最后一个柱的右侧。

感谢您的宝贵时间。

我可以想到(至少)两种方法来对齐两个图中的 x 轴:

  1. 两轴不对齐是因为在条形图中,geoms覆盖了x轴从0.5到27.5,而在另一个图中,数据只在1到27之间。原因是条形有宽度而点没有。您可以通过明确指定 x 轴范围来强制 axex 对齐。使用你的情节的定义,这可以通过

    来实现
    yes <- yes + scale_x_continuous(limits=c(0,28))
    no <- no + scale_x_continuous(limits=c(0,28))
    grid.arrange(no, yes)
    

    limits 设置 x 轴的范围。但请注意,海藻处理还不是很完美。 y 轴标签在上图中占据了 space 一点,因为数字有两位数。该图如下所示:

  2. 另一个解决方案有点复杂,但它的优点是 x 轴只绘制一次,并且 ggplot 确保对齐是完美的。它利用 this answer 中描述的分面和技巧。首先,数据必须通过

    组合成一个数据框
    all <- rbind(data.frame(other_data,type="other"),data.frame(data,type="data"))
    

    然后可以按如下方式创建绘图:

    ggplot(all,aes(x=x,y=y)) + facet_grid(type~.,scales = "free_y") +
       geom_bar(data=subset(all,type=="other"),stat="identity") +
       geom_point(data=subset(all,type=="data")) +
       geom_line(data=subset(all,type=="data"))
    

    诀窍是让分面由变量 type 构造,该变量之前用于标记两个数据集。但是每个 geom 只得到应该用那个特定 geom 绘制的数据子集。在facet_grid中,我也使用了scales = "free_y",因为两个y轴应该是独立的。该图如下所示:

您可以在定义数据框时通过指定其他名称来更改小平面的标签all。如果您想将它们全部删除,请将以下内容添加到您的绘图中:

+ theme(strip.background = element_blank(), strip.text = element_blank())

稍微扩展@Stibu 的 post:要对齐绘图,请使用 gtable(或查看 的答案)

library(ggplot2)
library(gtable)

data=data.frame(x=rep(1:27, each=5), y = rep(1:5, times = 27))
yes <- ggplot(data, aes(x = x, y = y))
yes <- yes + geom_point() + geom_line() + 
   scale_x_continuous(limits = c(0,28), expand = c(0,0))

other_data = data.frame(x = 1:27, y = 50:76  )

no <- ggplot(other_data, aes(x=x, y=y))
no <- no + geom_bar(stat = "identity") + 
   scale_x_continuous(limits = c(0,28), expand = c(0,0))

gYes = ggplotGrob(yes)   # get the ggplot grobs
gNo = ggplotGrob(no)

plot(rbind(gNo, gYes, size = "first"))   # Arrange and plot the grobs

编辑 要更改地块的高度:

g = rbind(gNo, gYes, size = "first")  # Combine the plots
panels <- g$layout$t[grepl("panel", g$layout$name)] # Get the positions for plot panels
g$heights[panels] <- unit(c(0.7, 0.3), "null") # Replace heights with your relative heights
plot(g)