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

如何在ggplot堆叠条形图中控制条形标签颜色

堆叠条形图标签颜色匹配对应条形的实现方法

当前堆叠条形图中,金色条形代表正数,红色条形代表负数,条形末端的数值显示正确,但标签颜色有误——标签颜色应与对应条形颜色一致。目前仅能将负数值标签改成红色,请问如何同时控制正负条形标签的颜色?

原代码

library("tidyverse")

red <- "#CD5C5C"
gold <- "#FCB700"

df <- structure(list(type = c("up", "up", "up", "up", "up", "down", 
                           "down", "down", "down", "down"), gic_term = c("1yr", "2yr", "3yr", 
                                                                         "4yr", "5yr", "1yr", "2yr", "3yr", "4yr", "5yr"), value = c(6, 
                                                                                                                                     1, 0, 0, 0, -2, -11, -14, -18, -22), value_to_display = c(6, 
                                                                                                                                                                                               1, 0, 0, 0, 2, 11, 14, 18, 22), vjust = c(-0.3, -0.3, -0.3, -0.3, 
                                                                                                                                                                                                                                         -0.3, 1.2, 1.2, 1.2, 1.2, 1.2), bar_num_col = c("#FCB700", "#FCB700", 
                                                                                                                                                                                                                                                                                         "#FCB700", "#FCB700", "#FCB700", "#C8F5C0", "#C8F5C0", "#C8F5C0", 
                                                                                                                                                                                                                                                                                         "#C8F5C0", "#C8F5C0")), row.names = c(NA, -10L), class = c("tbl_df", 
                                                                                                                                                                                                                                                                                                                                                    "tbl", "data.frame"))

ggplot(df, aes(fill = type, y = value, x = gic_term)) + 
  geom_bar(position = "stack", stat = "identity") +
  scale_fill_manual(values = c(red, gold)) +
  labs(title = "Stacked Bar Graph") +
  theme_minimal() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_blank(),
    legend.position = "none"
  ) +
  geom_text(aes(gic_term, label = value_to_display,  vjust = vjust, color = bar_num_col), size = 8)

解决方案

问题核心在于原数据中bar_num_col的负数标签颜色设成了绿色(#C8F5C0),和红色条形不匹配,且ggplot中直接映射颜色值需要用scale_color_identity()来识别。更规范的做法是利用已有的type变量同步颜色映射,无需额外颜色列。

方法1:修正颜色列并使用颜色恒等映射

先修正数据框里的bar_num_col,把负数对应的颜色改成红色,然后添加scale_color_identity()让ggplot直接使用颜色值:

library("tidyverse")

red <- "#CD5C5C"
gold <- "#FCB700"

# 修正bar_num_col的颜色值,down类型对应红色
df <- df %>% 
  mutate(bar_num_col = ifelse(type == "up", gold, red))

ggplot(df, aes(fill = type, y = value, x = gic_term)) + 
  geom_bar(position = "stack", stat = "identity") +
  scale_fill_manual(values = c(red, gold)) +
  labs(title = "Stacked Bar Graph") +
  theme_minimal() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_blank(),
    legend.position = "none"
  ) +
  geom_text(aes(label = value_to_display, vjust = vjust, color = bar_num_col), size = 8) +
  # 添加这一行让ggplot识别颜色值
  scale_color_identity()

方法2:利用type变量同步颜色映射

直接用type变量映射标签颜色,和填充色使用相同的颜色规则,更简洁:

library("tidyverse")

red <- "#CD5C5C"
gold <- "#FCB700"

ggplot(df, aes(fill = type, y = value, x = gic_term)) + 
  geom_bar(position = "stack", stat = "identity") +
  # 同步填充色和标签颜色的映射规则
  scale_fill_manual(values = c(down = red, up = gold)) +
  scale_color_manual(values = c(down = red, up = gold)) +
  labs(title = "Stacked Bar Graph") +
  theme_minimal() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_blank(),
    legend.position = "none"
  ) +
  # 用type映射颜色,无需额外列
  geom_text(aes(label = value_to_display, vjust = vjust, color = type), size = 8)

说明

  • 方法1适合需要自定义颜色列的场景,通过scale_color_identity()直接使用数据中的颜色值
  • 方法2更简洁,复用了type变量的映射关系,确保标签颜色和条形填充色完全同步,避免维护额外颜色列的麻烦

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 16:45:25