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

如何根据堆叠条形图填充色深浅控制geom_text标签颜色?

嘿,这个需求我之前折腾过好几次,终于摸出了一套靠谱的实现方法,给你一步步讲清楚!

实现堆叠条形图标签自动适配颜色的方案

1. 先搭好基础绘图框架

咱们先拿个示例数据来演示,你可以直接替换成自己的数据集:

library(ggplot2)
library(dplyr)

# 构造示例数据(你换成自己的真实数据就行)
df <- tibble(
  主分类 = rep(c("品类A", "品类B", "品类C"), each = 3),
  子分类 = rep(c("项X", "项Y", "项Z"), 3),
  数值 = c(20, 30, 50, 15, 45, 40, 25, 25, 50)
)

# 先画出基础的堆叠条形图
base_plot <- ggplot(df, aes(x = 主分类, y = 数值, fill = 子分类)) +
  geom_col(position = "stack")

2. 核心:给每个条形颜色计算亮度,判断标签色

这里用的是行业通用的相对亮度公式:L = 0.2126*R + 0.7152*G + 0.0722*B(R/G/B是0-1之间的数值),亮度大于0.5的属于浅色,配黑色标签;小于等于0.5的是深色,配白色标签。

先写个小函数来计算亮度,再给数据集加上标签色的判断:

# 计算颜色相对亮度的工具函数
calc_luminance <- function(color) {
  rgb_values <- col2rgb(color) / 255
  0.2126 * rgb_values[1,] + 0.7152 * rgb_values[2,] + 0.0722 * rgb_values[3,]
}

# 给数据集添加填充色、亮度、标签色的信息
df <- df %>%
  # 提取每个子分类对应的填充色(如果是自定义配色,直接替换成你的颜色向量就行)
  mutate(填充色 = scales::hue_pal()(length(unique(子分类)))[match(子分类, unique(子分类))]) %>%
  # 计算该颜色的亮度
  mutate(亮度 = calc_luminance(填充色)) %>%
  # 根据亮度判断标签用黑还是白
  mutate(标签色 = ifelse(亮度 > 0.5, "black", "white"))

3. 添加上自适应颜色的标签

把计算好的标签色映射到geom_text的颜色参数上,注意位置要和堆叠条形图对齐:

base_plot + geom_text(
  aes(label = 数值, color = I(标签色)),  # 用I()直接指定颜色,避免ggplot自动映射图例
  position = position_stack(vjust = 0.5),  # 让标签居中显示在条形里
  size = 4  # 可以根据需求调整标签大小
)

额外小提示

  • 如果你的填充色是手动指定的(比如用scale_fill_manual),直接把你的颜色向量对应到每个子分类就行,不用scales::hue_pal()这一步。
  • 亮度阈值可以灵活调整:如果觉得某些浅色还是不够清晰,把阈值调高到0.6;如果深色标签还是看不清,把阈值调低到0.4就行。

这样就能完美实现深色条形配白标签、浅色条形配黑标签,标签可读性直接拉满!

内容的提问来源于stack exchange,提问作者SkyWalker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:56:24