如何在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
相关产品推荐
相关产品推荐

