【问题标题】:Line up columns of bar graph with points of line plot with ggplot使用 ggplot 将条形图的列与线图的点对齐
【发布时间】:2015-05-24 16:45:27
【问题描述】:

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

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=0.5,最后一个条的右边缘位于 x=27.5。第一个和最后一个点位于 x=1 和 x=27。因此,对齐条形的点和边缘似乎很不自然,因为这意味着两个轴的缩放比例不同。让条形的中心与点对齐不是更有意义吗?
  • 如何将条的中心与点对齐?
  • 查看曲目包,here is an example

标签: r ggplot2


【解决方案1】:

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

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)

【讨论】:

  • 有没有办法改变地块的高度,使第二个地块的高度小于第一个地块的高度?类似于在 grid.arrange() 中使用 heights = c(0.7,0.3) 的方式
  • this answerthis answer。另外,我添加了一个编辑。
【解决方案2】:

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

  1. 这两个轴不对齐,因为在条形图中,geoms 覆盖了从 0.5 到 27.5 的 x 轴,而在另一个图中,数据仅在 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 轴的范围。但请注意,alginment 仍然不是很完美。 y 轴标签在上图中占据了更多空间,因为数字有两位数。情节如下所示:

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

【讨论】:

    猜你喜欢
    • 2015-08-27
    • 2021-08-10
    • 2015-10-15
    • 1970-01-01
    • 1970-01-01
    • 2017-08-03
    • 1970-01-01
    • 2018-05-02
    • 1970-01-01
    相关资源
    最近更新 更多