我有一个线图,我希望根据某列是否为1来覆盖背景中的矩形或彩色条带。
以下是一个例子:
df <- data.frame(date = seq.Date(as.Date("2015-01-01"), as.Date("2016-12-01"), by = "month"),
value = c(rep(NA, 5), rep(1, 2), rep(NA, 3), rep(1, 10), rep(NA, 4)))
df2 <- data.frame(date = seq.Date(as.Date("2015-01-01"), as.Date("2016-12-01"), by = "month"),
values = c(rep(1, 10), rep(2, 10), rep(3, 4)))
我尝试过:
ggplot(df2, aes(x = date, y = values)) +
geom_line() +
geom_tile(data = df, aes(fill = "value"), inherit.aes = FALSE)
Error in eval(substitute(list(...)), `_data`, parent.frame()) :
object 'x' not found
In addition: Warning messages:
1: In min(x, na.rm = na.rm) :
no non-missing arguments to min; returning Inf
2: In max(x, na.rm = na.rm) :
我只想获得线条图,然后df$value
1
的背景颜色为灰色。
从Melissa的解决方案来看,我很接近,但却变得奇怪:
答案 0 :(得分:2)
你需要稍微玩这个,但这应该可以让你获得你想要的大部分内容:
df3 <- left_join(df2, df)
ggplot(df3, aes(x = date, y = values)) +
geom_line() +
geom_tile(aes(x = date, fill = !is.na(value)), width = 30, height = .4, alpha = 0.5, color = NA) +
scale_fill_manual(values = c("gray20", NA))
或让背景在y轴的整个范围内延伸:
ggplot(df3, aes(x = date, y = values)) +
geom_line() +
geom_tile(aes(x = date, fill = !is.na(value)), width = 30, height = Inf, alpha = 0.5) +
scale_fill_manual(values = c("gray20", NA))
此时宽度不是很正确 - 您可以尝试切换到geom_rect
以按左右点而不是中间点来定义宽度(请参阅geom_rect
的说明或geom_tile
让部分得到解决。
答案 1 :(得分:2)
以下是geom_rect
的答案,这是此应用程序的另一种选择。 ggplot
非常宽容地对geom
规范中的数据进行子集化,所以这样的事情可能对您的情况有用:
df <- data.frame(date = seq.Date(as.Date("2015-01-01"), as.Date("2016-12-01"), by = "month"),
value = c(rep(1, 6), rep(NA, 4), rep(1, 10), rep(NA, 4)))
df2 <- data.frame(date = seq.Date(as.Date("2015-01-01"), as.Date("2016-12-01"), by = "month"),
values = c(rep(1, 10), rep(2, 10), rep(3, 4)))
library(ggplot2)
library(lubridate)
ggplot() +
geom_rect(data=subset(df,value==1), aes(xmin=date, xmax=date+months(1), ymin=-Inf, ymax=Inf), fill="light grey", colour=NA) +
geom_line(data=df2, aes(x = date, y = values)) +
theme_classic()
此方法还单独维护df
和df2
,但我同意加入它们会更好,因为每个都有相同的日期。