You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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图例:

  1. 先安装并加载包:
install.packages("ggnewscale")
library(ggnewscale)
  1. 修改绘图代码:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 21:22:48