如何在ggplot中拆分geom_tile与geom_bar组合图的图例?
拆分ggplot中geom_bar与geom_tile的独立图例
你的问题出在两个图层都使用了fill美学映射,导致图例被合并到一起。完全可以继续使用geom_tile,它是实现底部色块标注的合适选择,只需调整美学映射的设置就能拆分图例。
示例数据
for_bar_plot <- read.table(text=" sample category count Date Sample1 cat1 65 221116 Sample1 cat2 8978 221116 Sample2 cat1 3961 221116 Sample2 cat2 341 221116 Sample3 cat1 47 221116 Sample3 cat2 9860 221116 Sample4 cat1 54 230331 Sample4 cat2 7625 230331 Sample5 cat1 70 230331 Sample5 cat2 9807 230331", header=TRUE)
解决方案
方法1:用ggnewscale创建独立的fill图例(推荐)
这个包专门解决同一张图中多比例尺的冲突问题,能让两个图层分别使用独立的fill图例:
- 先安装并加载包:
install.packages("ggnewscale") library(ggnewscale)
- 修改绘图代码:
ggplot(for_bar_plot) + # 绘制柱状图,设置第一个fill图例 geom_bar(aes(x = sample, fill = category, y = count), position = "stack", stat = "identity") + scale_fill_manual(name = "Category", values = c("cat1" = "#619CFF", "cat2" = "#F8766D")) + # 自定义配色和图例名称 # 启用新的fill比例尺,分隔两个图例 new_scale_fill() + # 绘制tile图层,设置第二个fill图例 geom_tile(aes(x = sample, y = -3000, fill = factor(Date), height = 3000)) + scale_fill_manual(name = "Date", values = c("221116" = "#C77CFF", "230331" = "#00BA38")) + # 调整y轴范围,确保底部tile完全显示 ylim(-3000, max(for_bar_plot$count))
方法2:替换其中一个图层的美学映射(无需额外装包)
如果不想安装新包,可以把geom_tile的fill换成其他美学属性,比如color(给tile加边框区分)或alpha(用透明度区分),但视觉效果不如纯色填充:
ggplot(for_bar_plot) + geom_bar(aes(x = sample, fill = category, y = count), position = "stack", stat = "identity") + # 将tile的fill替换为color,同时设置tile内部填充为纯色 geom_tile(aes(x = sample, y = -3000, color = factor(Date), height = 3000), fill = "gray90") + scale_color_manual(name = "Date", values = c("221116" = "darkblue", "230331" = "darkgreen")) + ylim(-3000, max(for_bar_plot$count))
内容的提问来源于stack exchange,提问作者swbarnes2
相关产品推荐
相关产品推荐

