在R的ggplot2中为大数据集的条形图添加计数标签
问题
我绘制了展示汽车测试数量的条形图,尝试为每个条形添加对应计数标签,但标签聚集在条形底部。以下是我的代码:
cars %>% mutate(Brand = fct_reorder(Brand,Total-test,.fun = sum)) %>% ggplot(aes(x=Brand, y=Total)) + geom_bar(stat="identity", fill="blue",width=0.4) + coord_flip()+ geom_text(aes(label=Total-test), hjust=-10)
数据样例(前50条):
structure(list(vehicle = c("ALFA ROMEO-147-2003", "ALFA ROMEO-147-2004", "ALFA ROMEO-147-2005", "ALFA ROMEO-147-2006", "ALFA ROMEO-147-2007", "ALFA ROMEO-147-2008", "ALFA ROMEO-147-2010", "ALFA ROMEO-155-1997", "ALFA ROMEO-156-1999", "ALFA ROMEO-156-2000", "ALFA ROMEO-156-2001", "ALFA ROMEO-156-2002", "ALFA ROMEO-156-2003", "ALFA ROMEO-156-2004", "ALFA ROMEO-156-2005", "ALFA ROMEO-159-2006", "ALFA ROMEO-159-2007", "ALFA ROMEO-159-2008", "ALFA ROMEO-159-2009", "ALFA ROMEO-159-2010", "ALFA ROMEO-159-2011", "ALFA ROMEO-166-2004", "ALFA ROMEO-BRERA-2006", "ALFA ROMEO-BRERA-2007", "ALFA ROMEO-BRERA-2008", "ALFA ROMEO-GIULIA-2017", "ALFA ROMEO-GIULIETTA-2010", "ALFA ROMEO-GIULIETTA-2011", "ALFA ROMEO-GIULIETTA-2012", "ALFA ROMEO-GIULIETTA-2013", "ALFA ROMEO-GIULIETTA-2014", "ALFA ROMEO-GIULIETTA-2015", "ALFA ROMEO-GIULIETTA-2016", "ALFA ROMEO-GIULIETTA-2017", "ALFA ROMEO-GT-2005", "ALFA ROMEO-GT-2006", "ALFA ROMEO-GT-2007", "ALFA ROMEO-GT-2008", "ALFA ROMEO-GT-2009", "ALFA ROMEO-GT-2010", "ALFA ROMEO-MITO-2009", "ALFA ROMEO-MITO-2010", "ALFA ROMEO-MITO-2011", "ALFA ROMEO-MITO-2017", "ALFA ROMEO-OTHER-1996", "ALFA ROMEO-OTHER-2001", "ALFA ROMEO-OTHER-2002", "ALFA ROMEO-OTHER-2003", "ALFA ROMEO-OTHER-2009", "ALFA ROMEO-OTHER-2010" ), Vehicle Make= c("ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO", "ALFA ROMEO"), Vehicle Model= c("147", "147", "147", "147", "147", "147", "147", "155", "156", "156", "156", "156", "156", "156", "156", "159", "159", "159", "159", "159", "159", "166", "BRERA", "BRERA", "BRERA", "GIULIA", "GIULIETTA", "GIULIETTA", "GIULIETTA", "GIULIETTA", "GIULIETTA", "GIULIETTA", "GIULIETTA", "GIULIETTA", "GT", "GT", "GT", "GT", "GT", "GT", "MITO", "MITO", "MITO", "MITO", "OTHER", "OTHER", "OTHER", "OTHER", "OTHER", "OTHER"), Year Of Birth= c(2003, 2004, 2005, 2006, 2007, 2008, 2010, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2004, 2006, 2007, 2008, 2017, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2005, 2006, 2007, 2008, 2009, 2010, 2009, 2010, 2011, 2017, 1996, 2001, 2002, 2003, 2009, 2010), Total = c(9, 12, 19, 24, 43, 46, 13, 7, 9, 7, 22, 8, 37, 42, 21, 40, 123, 164, 83, 56, 27, 6, 9, 14, 10, 94, 17, 92, 15, 10, 13, 25, 8, 25, 35, 40, 45, 51, 12, 10, 43, 26, 33, 7, 6, 16, 10, 7, 32, 45), PASS = c(2, 3, 6, 8, 10, 23, 4, 3, 4, 0, 5, 1, 12, 12, 6, 17, 42, 56, 30, 20, 13, 0, 3, 3, 6, 56, 10, 58, 8, 9, 11, 22, 5, 23, 13, 11, 16, 16, 3, 3, 26, 14, 17, 5, 4, 7, 5, 2, 18, 16), PASS % = c(22.2, 25, 31.6, 33.3, 23.3, 50, 30.8, 42.9, 44.4, 0, 22.7, 12.5, 32.4, 28.6, 28.6, 42.5, 34.1, 34.1, 36.1, 35.7, 48.1, 0, 33.3, 21.4, 60, 59.6, 58.8, 63, 53.3, 90, 84.6, 88, 62.5, 92, 37.1, 27.5, 35.6, 31.4, 25, 30, 60.5, 53.8, 51.5, 71.4, 66.7, 43.8, 50, 28.6, 56.3, 35.6)), class = "data.frame", row.names = c(NA, -50L))
注:Total(总测试数)刻度最高可达200000,请求修正标签位置,使其正确显示在对应条形上。
解决方案
标签位置异常的核心原因有两个:
- 未给
geom_text指定匹配条形高度的y轴位置,且原始数据未按品牌汇总,导致同一品牌出现多个重复条形; coord_flip()反转了坐标轴逻辑,同时hjust=-10的数值过大,直接把标签推到了画布外的底部区域。
修正后的代码如下:
# 先按品牌汇总数据,计算总测试数和要显示的计数(假设是未通过测试数:Total-PASS) cars_summary <- cars %>% group_by(`Vehicle Make`) %>% summarise(Total = sum(Total), Unpassed_Count = sum(Total - PASS)) %>% mutate(`Vehicle Make` = fct_reorder(`Vehicle Make`, Total, .fun = sum)) ggplot(cars_summary, aes(x=`Vehicle Make`, y=Total)) + geom_bar(stat="identity", fill="blue", width=0.4) + coord_flip() + # 将标签定位在条形顶端,hjust=-0.1让标签在条形右侧留间距 geom_text(aes(label=Unpassed_Count), y=~Total, hjust=-0.1, size=3.5) + # 扩展x轴范围,避免大数值标签被截断(预留10%的空间) xlim(NA, max(cars_summary$Total) * 1.1)
关键调整说明:
- 数据汇总:按
Vehicle Make(即你代码中的Brand)分组求和,确保每个品牌对应一个条形; - 标签定位:明确设置
y=Total,让标签对齐对应条形的顶端; - 对齐参数:
coord_flip()后,hjust控制水平方向(原垂直方向)的对齐,-0.1的数值既能让标签脱离条形,又不会偏移过远; - 轴范围扩展:针对Total最大值达200000的情况,扩展x轴上限,保证标签完整显示。
内容的提问来源于stack exchange,提问作者highclef
相关产品推荐
相关产品推荐

