使用ggfittext::geom_bar_text设置bold字体致文本错位混乱
ggfittext 堆叠条形图标签加粗后错位问题的解决
问题描述
使用ggfittext::geom_bar_text()给水平堆叠条形图添加数值标签时,只要通过fontface美学映射将部分数值设为粗体,就会出现标签不居中、数值错乱的情况——比如示例里cat1为"C"的组,标签位置偏移还跟数值对不上。
原因分析
这是ggfittext的一个已知问题:当把fontface作为美学映射时,函数会默认将其当作分组变量,干扰了堆叠位置的计算逻辑,导致标签的位置和对应数值出现错误匹配。
解决方案
方案1:手动计算标签位置(推荐,稳定可靠)
放弃geom_bar_text的自动堆叠逻辑,自己计算每个标签的中点位置,用普通的geom_text实现需求,既能保留字体加粗的设置,又不会打乱堆叠的计算逻辑。
代码示例:
library(ggplot2) library(scales) library(dplyr) df <- data.frame(cat1 = rep(c("A", "B", "C"), each = 3), cat2 = rep(c("D", "E", "F"), 3), perc = c(0, .6, .4, .26, .24, .5, .3, .3, .4), fface = c("plain", "bold", "plain", "bold", "plain", "plain", "plain", "plain", "bold")) # 按cat1分组,计算每个条形的中点x坐标 df <- df %>% group_by(cat1) %>% mutate(cum_perc = cumsum(perc), label_x = cum_perc - perc/2) %>% ungroup() ggplot(df, aes(y = cat1, fill = cat2, x = perc)) + geom_col() + geom_text(aes(x = label_x, label = percent(perc, accuracy = .1), fontface = fface), hjust = 0.5)
方案2:调整geom_bar_text参数(临时 workaround)
如果一定要使用geom_bar_text,可以把fontface从全局美学映射中移除,只在geom_bar_text内部指定,同时显式设置position_stack来确保堆叠位置正确。不过这个方法在部分版本的ggfittext中可能仍存在兼容性问题。
代码示例:
library(ggplot2) library(ggfittext) library(scales) df <- data.frame(cat1 = rep(c("A", "B", "C"), each = 3), cat2 = rep(c("D", "E", "F"), 3), perc = c(0, .6, .4, .26, .24, .5, .3, .3, .4), fface = c("plain", "bold", "plain", "bold", "plain", "plain", "plain", "plain", "bold")) ggplot(df, aes(y = cat1, fill = cat2, x = perc)) + # 全局aes去掉fontface geom_col() + geom_bar_text(aes(label = percent(perc, accuracy = .1), fontface = fface), position = position_stack(vjust = 0.5), place = "centre")
测试结果
方案1的代码可以稳定实现标签居中显示,粗体数值也能正确对应,不会出现错乱;方案2在部分环境下生效,但兼容性不如方案1。
内容的提问来源于stack exchange,提问作者swolf
相关产品推荐
相关产品推荐

