合并多个geom_rect()有什么问题?

3

我有一个简单的数据集,其中包含:

tmp
#  xmin xmax ymin ymax
#     0    1    0   11
#     0    1   11   18
#     0    1   18   32

我希望在绘图中使用多个geom_rect()。这是我的做法,看起来很好。

cols = c('red', 'blue', 'yellow')
x = seq(0, 1, 0.05)

ggplot(data = NULL, aes(x = 1, y = 32)) + 
  geom_rect(data = NULL, aes(xmin=x, xmax = x + 0.05, ymin=0, ymax=11, fill = x), color = cols[1] ) + 
  geom_rect(data = NULL, aes(xmin=x, xmax = x + 0.05, ymin=11, ymax=18, fill = x), color = cols[2])  + 
  geom_rect(data = NULL, aes(xmin=x, xmax = x + 0.05, ymin=18, ymax=32, fill = x), color = cols[3]) 

enter image description here

然而,将这三个geom_rect()调用放入循环中,我得到了一个不同的图表。看起来这些geom已经合并在一起了。有人能告诉我循环代码有什么问题吗?

g1 = ggplot(data = NULL, aes(x = 1, y = 32))

for (i in 1:3) {
  yl = tmp[i, ]$ymin
  yu = tmp[i, ]$ymax
  g1 = g1 + geom_rect(data = NULL, aes(xmin=x, xmax = x + 0.05, ymin=yl, ymax=yu, fill = x), color = cols[i]) 
}
g1

enter image description here


2
它并不是将它们合并,而只是绘制最后一个。这与aes()参数的惰性评估有关。循环的每次迭代都与相同的ylyu变量相关联,因此当您在循环中更新它们时,当您实际“绘制”ggplot对象时,只有最后一个值存在。这似乎是构建图的一种非常奇怪的方式。更好的方法是先正确构造一个数据框,其中包含您希望绘制的所有点。 - MrFlick
2个回答

2
另一个答案很好。如果你真的想坚持使用原始代码,这里有一个基于你的原始代码稍微修改过的解决方案。
g1 = ggplot(data = NULL, aes(x = 1, y = 32))
for (i in 1:3) {
  yl = tmp[i, 3] ## no need to use $, just column index is fine
  yu = tmp[i, 4] ## no need to use $, just column index is fine
  ## ggplot2 works with data frame. So you convert yl, yu into data frame.
  ## then it knows from where to pull the data.
  g1 = g1 + geom_rect(data=data.frame(yl,yu), aes(xmin=x, xmax=x+0.05, ymin=yl, ymax=yu, fill=x), color=cols[i]) 
}
g1

enter image description here


1
为了避免@MrFlick解释的注意事项,您可以单独定义data,例如:
g1 = ggplot(data = NULL)

for (i in 1:3) {
  g1 = g1 + geom_rect(data = tmp[i, ], 
                      aes(xmin = x, xmax = x + 0.05, 
                          ymin = ymin, ymax = ymax, fill = x), color = cols[i]) 
}
g1

并且你将得到你想要的图表。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接