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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 20:35:00