如何用ggplot的geom_area实现Count变量的双色区域填充?
如何在ggplot2的geom_area中实现基于Y轴阈值的双色填充?
你想要实现的是根据Count值是否≥12.5来给geom_area填充不同颜色,之前的子集方法没成功主要是因为只处理了其中一部分区域,而且语法上存在小问题。其实完全可以用geom_area来实现这个需求,下面是两种最优的实现方式:
方法1:直接在aes中用ifelse控制填充区域
这种方法不需要提前修改数据集,直接在图层里判断Count的阈值,代码简洁直观:
library(ggplot2) ggplot(df_shadded_graph, aes(x = Date)) + # 先绘制灰色填充(Count < 12.5的部分) geom_area(aes(y = ifelse(Count < 12.5, Count, NA)), fill = "grey", alpha = .99) + # 再绘制黑色填充(Count ≥ 12.5的部分) geom_area(aes(y = ifelse(Count >= 12.5, Count, NA)), fill = "black", alpha = .99) + # 保留你原来的其他图层设置 geom_line(aes(y = Underpricing * 100), colour = "grey", linetype = "longdash") + scale_y_continuous(sec.axis = sec_axis(~. / 100, name = "Underpricing")) + geom_hline(yintercept = 12.5) + theme_minimal()
方法2:提前预处理数据集(代码更清晰)
如果你觉得在aes里写ifelse有点杂乱,可以先给数据集新增两个变量,分别对应不同阈值的Count值,后续绘图逻辑会更易懂:
library(ggplot2) library(dplyr) # 预处理数据,拆分不同阈值的Count值 df_shadded_graph <- df_shadded_graph %>% mutate( Count_black = ifelse(Count >= 12.5, Count, NA), Count_grey = ifelse(Count < 12.5, Count, NA) ) # 绘图 ggplot(df_shadded_graph, aes(x = Date)) + geom_area(aes(y = Count_grey), fill = "grey", alpha = .99) + geom_area(aes(y = Count_black), fill = "black", alpha = .99) + geom_line(aes(y = Underpricing * 100), colour = "grey", linetype = "longdash") + scale_y_continuous(sec.axis = sec_axis(~. / 100, name = "Underpricing")) + geom_hline(yintercept = 12.5) + theme_minimal()
为什么你之前的代码没成功?
你之前的代码geom_area(data = subset(df_shadded_graph, zero_one == 1, fill="black", alpha=.99))有两个核心问题:
- 语法错误:
subset函数的括号使用错误,应该是subset(df_shadded_graph, zero_one == 1),你把fill参数写到了subset的括号里,这会被当成subset的参数而非geom_area的参数; - 逻辑缺失:只绘制了
zero_one=1的黑色区域,没有绘制zero_one=0的灰色区域,所以无法呈现完整的双色填充效果。
你的简化数据集:
df_shadded_graph <- structure(list(Date = structure(c(1025481600, 1028160000, 1030838400, 1033430400, 1036108800, 1038700800, 1041379200, 1044057600, 1046476800, 1049155200, 1051747200, 1054425600, 1057017600, 1059696000, 1062374400, 1064966400, 1067644800, 1070236800, 1072915200, 1075593600, 1078099200, 1080777600, 1083369600, 1086048000, 1088640000, 1091318400), class = c("POSIXct", "POSIXt"), tzone = "UTC"), Count = c(5.33333333333333, 2.33333333333333, 3.66666666666667, 6.66666666666667, 8.66666666666667, 5.33333333333333, 3.33333333333333, 1.66666666666667, 1.66666666666667, 1, 1.66666666666667, 4, 5.66666666666667, 6.66666666666667, 8.33333333333333, 11.3333333333333, 16.6666666666667, 14.3333333333333, 15.3333333333333, 13.3333333333333, 15.6666666666667, 14.3333333333333, 18.3333333333333, 23.6666666666667, 24.3333333333333, 20), Underpricing = c(0.0281112960367963, 0.00954323052149139, 0.0129313986013986, 0.0296151983272675, 0.0542382142002834, 0.0413068155988848, 0.0178396825396825, -0.00869082021936099, -0.00869082021936099, 0.050384179780639, 0.0962599206349206, 0.1782458943856, 0.16362838849032, 0.155155878713463, 0.110998297207745, 0.106699976872014, 0.113896570632104, 0.162480658578345, 0.176346448849018, 0.157754181912185, 0.148675489256975, 0.130041460117814, 0.136243778466198, 0.0743238088052681, 0.0478918997193753, 0.0596987903377546), zero_one = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)), .Names = c("Date", "Count", "Underpricing", "zero_one"), row.names = c(NA, -26L), class = c("tbl_df", "tbl", "data.frame"))
内容的提问来源于stack exchange,提问作者SCW16




