如何为ggplot各facet添加对应组geom_hline且不修改原数据?
解决方法:为每个分面添加对应分组的最高价格水平线
核心思路是让统计计算跟随分面的cut分组执行,且完全不需要修改原diamonds数据集,以下提供两种可行方案:
方案1:用stat_summary直接生成分组统计(极简写法)
利用stat_summary自动按分面分组计算最大值,无需额外创建数据集:
library(tidyverse) data(diamonds) ggplot(data = diamonds) + geom_point(mapping = aes(x = carat, y = price), color = "blue") + # 按cut分组生成最高价格水平线 stat_summary( aes(yintercept = after_stat(y)), fun = max, geom = "hline", color = "seagreen" ) + # 为每个分面添加对应分组的最高价格标注 stat_summary( aes(label = scales::comma(after_stat(y), accuracy = 1)), fun = max, geom = "text", x = 3.5, y = after_stat(y) + 200, # 让标注在水平线上方偏移一点 size = 5, color = "seagreen", fontface = "bold.italic" ) + facet_wrap(facets = "cut")
after_stat(y)会提取stat_summary按cut分组计算出的最大值,自动匹配对应分面。
方案2:提前生成分组统计数据集(更灵活)
如果需要精细调整标注位置、添加额外统计信息,可单独生成分组统计的小数据集,再传递给图层:
library(tidyverse) data(diamonds) # 生成每个cut分组的最高价格数据,不改动原数据集 cut_max_prices <- diamonds %>% group_by(cut) %>% summarise(max_price = max(price), .groups = "drop") ggplot(data = diamonds) + geom_point(mapping = aes(x = carat, y = price), color = "blue") + # 用分组统计数据绘制水平线 geom_hline( data = cut_max_prices, aes(yintercept = max_price), color = "seagreen" ) + # 添加对应分组的价格标注 geom_text( data = cut_max_prices, aes(x = 3.5, y = max_price + 200, label = scales::comma(max_price, accuracy = 1)), size = 5, color = "seagreen", fontface = "bold.italic" ) + facet_wrap(facets = "cut")
原代码问题说明
原代码中geom_hline(aes(yintercept=max(price)))的max(price)是对整个diamonds数据集计算的全局最大值,ggplot不会自动按分面分组执行统计,因此所有分面都显示同一水平线。上述两种方案均实现了按cut分组计算最大值,从而匹配对应分面。
内容的提问来源于stack exchange,提问作者Kiki Liu
相关产品推荐
相关产品推荐

