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

如何在ggplot2条形图的文本标签下添加可控制宽度的彩色下划线?

给ggplot2条形图标签添加可自定义的彩色下划线

我用以下代码生成了一份条形图,目前运行正常,但希望在条形右侧的数值标签(如89、86.4%)下方添加彩色下划线,且能控制下划线的宽度,请问如何通过程序化方式实现?

require(ggplot2)
require(dplyr)

df <- data.frame (Origin = c("Canada", "Canada","USA","USA"),
                  Year = c("2021", "2022","2021","2022"),
                  Sales = c(103, 192, 144, 210),
                  diff = c(89, " ",66," "),
                  perdiff = c(86.4, " ",45.83," "))


df <- df %>% mutate(label= ifelse(diff!=" ",paste0(diff,", ",perdiff,'%'),NA))
ggplot(df, aes(fill=Year, y=Origin, x=Sales)) + 
  geom_bar(position="dodge", stat="identity")+ 
  geom_text(aes(label=label, x=200), fontface='bold') +
  scale_x_continuous(breaks=seq(0,200,25))+
  theme()

可以用geom_segment()来模拟下划线,因为geom_text本身不支持自定义下划线样式,通过线段可以灵活控制颜色、宽度和位置。具体实现方案如下:

固定宽度下划线实现

先整理数据标记需要添加下划线的行,再通过geom_segment()绘制线段,自定义位置、颜色和粗细:

require(ggplot2)
require(dplyr)

df <- data.frame (Origin = c("Canada", "Canada","USA","USA"),
                  Year = c("2021", "2022","2021","2022"),
                  Sales = c(103, 192, 144, 210),
                  diff = c(89, " ",66," "),
                  perdiff = c(86.4, " ",45.83," "))

# 处理标签和下划线的位置数据
df <- df %>% 
  mutate(label= ifelse(diff!=" ",paste0(diff,", ",perdiff,'%'),NA),
         # 标记需要添加下划线的行
         has_underline = !is.na(label),
         # 下划线的y轴偏移(根据文本大小调整,这里用-0.1)
         underline_y = as.numeric(factor(Origin)) - 0.1,
         # 自定义下划线宽度:设置x起点和终点
         underline_x_start = 190,
         underline_x_end = 210)

ggplot(df, aes(fill=Year, y=Origin, x=Sales)) + 
  geom_bar(position="dodge", stat="identity")+ 
  # 先绘制下划线(放在文本下方,所以先画)
  geom_segment(aes(x=underline_x_start, xend=underline_x_end,
                   y=underline_y, yend=underline_y,
                   color=Origin), # 按Origin区分颜色,也可设固定色如"red"
               size=1.2, # 控制下划线粗细
               data = filter(df, has_underline)) +
  # 绘制标签
  geom_text(aes(label=label, x=200), fontface='bold') +
  scale_x_continuous(breaks=seq(0,220,25))+ # 扩展x轴范围避免下划线被截断
  scale_color_manual(values = c("Canada"="blue", "USA"="red"))+ # 自定义下划线颜色
  theme()

匹配文本长度的动态下划线

如果希望下划线宽度自动匹配标签文本长度,可以用strwidth()计算文本宽度,动态调整x轴起止位置:

require(ggplot2)
require(dplyr)

df <- data.frame (Origin = c("Canada", "Canada","USA","USA"),
                  Year = c("2021", "2022","2021","2022"),
                  Sales = c(103, 192, 144, 210),
                  diff = c(89, " ",66," "),
                  perdiff = c(86.4, " ",45.83," "))

# 动态计算下划线宽度
df <- df %>% 
  mutate(label= ifelse(diff!=" ",paste0(diff,", ",perdiff,'%'),NA),
         has_underline = !is.na(label),
         underline_y = as.numeric(factor(Origin)) - 0.1,
         # 计算文本宽度并转换为x轴单位(系数80根据x轴范围调整)
         text_width = strwidth(label, units="inches") * 80,
         # 基于文本中心(x=200)计算下划线起止位置
         underline_x_start = 200 - text_width/2,
         underline_x_end = 200 + text_width/2)

ggplot(df, aes(fill=Year, y=Origin, x=Sales)) + 
  geom_bar(position="dodge", stat="identity")+ 
  geom_segment(aes(x=underline_x_start, xend=underline_x_end,
                   y=underline_y, yend=underline_y,
                   color=Origin),
               size=1.2,
               data = filter(df, has_underline)) +
  geom_text(aes(label=label, x=200), fontface='bold') +
  scale_x_continuous(breaks=seq(0,220,25))+
  scale_color_manual(values = c("Canada"="blue", "USA"="red"))+
  theme()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 04:35:28