在geom_bar绘图中使用geom_text/geom_label添加标签的方法问询
问题
我正在绘制特定研究主题的科学论文发表时间线,希望通过label变量在对应柱状条上添加作者及年份信息。但使用geom_text()或geom_label()时需设置y美学参数,而我使用geom_bar()时并不需要该参数,请问是否有解决办法?
可复现代码:
year <- c(2012, 2023, 2020, 2023, 2019, 2017, 2022, 2022, 2018, 2021, 2016, 2017, 2019, 2020, 2019, 2022, 2016, 2021, 2020, 2022, 2022, 2020, 2015, 2021, 2021, 2024, 2023) label <- c('Henry et al. (2012)', 'Breitmayer et al. (2023)', 'Deutsch & Piccirillo (2020)', 'Engelke et al. (2023)', 'Gerull et al. (2019)', 'Goldberg et al. (2017)', 'Kraft et al. (2022)', 'Lourenco et al. (2022)', 'Muniandi et al. (2018)', 'Prakash et al. (2021)', 'Probst et al. (2016)', 'Probst et al. (2017)', 'Pryss et al. (2019)', 'Pryss et al. (2020)', 'Pryss et al. (2019)', 'Schlee et al. (2022)', 'Schlee et al. (2016)', 'Schlee, Simoes & Pryss (2021)', 'Schleicher et al. (2020)', 'Shahania et al. (2022)', 'Simoes et al. (2022)', 'Unnikrishnan et al. (2020)', 'Wilson et al. (2015)', 'Lourenco et al. (2021)', 'Dode et al. (2021)', 'Engelke et al. (2024)', 'Kleinau et al. (2023)') topic <- c('feasibility', 'ML', 'review', 'outcome', 'feasibility', 'feasibility', 'software', 'feasibility', 'ML', 'ML', 'symptom interaction', 'symptom interaction', 'retrospective comparison', 'ML', 'software', 'feasibility', 'feasibility', 'outcome', 'ML', 'ML', 'symptom interaction', 'ML', 'feasibility', 'feasibility', 'retrospective comparison', 'outcome', 'ML') df_hist <- data.frame(year, label, topic) ggplot(df_hist, aes(year, fill = topic, group = topic)) + geom_bar() + scale_fill_manual(values=c("#F09EA7", "#F6CA94", "#FAFABE", "#C1EBC0", "#C7CAFF", "#CDABEB", "#F6C2F3")) + theme_bw()
解决方案
方法1:利用position_stack自动计算y位置
geom_bar()默认用position_stack()堆叠条形,geom_text()/geom_label()可以复用这个位置逻辑,通过设置position = position_stack(vjust = 0.5)让文本居中显示在对应的条形块内,无需手动指定y值。
修改后的代码:
ggplot(df_hist, aes(year, fill = topic, group = topic)) + geom_bar() + # 添加标签,用position_stack让文本居中 geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 3, # 缩小文本避免重叠 color = "black") + scale_fill_manual(values=c("#F09EA7", "#F6CA94", "#FAFABE", "#C1EBC0", "#C7CAFF", "#CDABEB", "#F6C2F3")) + theme_bw() + # 旋转x轴标签提升可读性 theme(axis.text.x = element_text(angle = 45, hjust = 1))
方法2:预处理数据计算精确y位置
如果需要更精细控制标签位置,可以先对数据分组统计,计算每个条形块的中间位置作为y坐标:
library(dplyr) # 预处理:计算每个(year, topic)组的计数和标签的居中位置 df_label <- df_hist %>% group_by(year, topic) %>% mutate(count = n()) %>% ungroup() %>% arrange(year, topic) %>% group_by(year) %>% mutate(cumulative = cumsum(count) - count/2) # 取条形块的中间值作为y坐标 # 绘图 ggplot(df_label, aes(year, fill = topic, group = topic)) + geom_bar() + geom_text(aes(y = cumulative, label = label), size = 3, color = "black") + scale_fill_manual(values=c("#F09EA7", "#F6CA94", "#FAFABE", "#C1EBC0", "#C7CAFF", "#CDABEB", "#F6C2F3")) + theme_bw() + theme(axis.text.x = element_text(angle = 45, hjust = 1))
额外提示
- 若同一年同一主题下论文较多导致标签重叠,可安装
ggrepel包,用geom_label_repel()替代geom_text(),让标签自动避开重叠。 - 调整
size参数可以控制文本大小,适配不同的图表尺寸。
内容的提问来源于stack exchange,提问作者Milena
相关产品推荐
相关产品推荐

