如何为ggplot图表添加分组空白与额外X轴标签
问题描述
需要制作以var为X轴的geom_point图表,var分为以下三大组:
- Strength组:Weak、Strong
- Race/Ethnicity组:White、Black、Hispanic
- City组:Springfield、Buxton、Artowne、Friedsville、Alexandria、Oldmill
同时要求:
- 各组之间添加空白间隔
- 除Total外,每个大组下方添加居中的组标签(如Race/Ethnicity组下方添加对应组名标签)
原始代码与示例数据如下:
order1 <- c("Total", "Weak", "Strong", "White", "Black", "Hispanic", "Springfield", "Buxton", "Artowne", "Friedsville", "Alexandria", "Oldmill") data %>% ggplot(., aes(y = mean, x = var, color = var)) + geom_point() + geom_pointrange(aes(ymin = lower, ymax = upper)) + scale_x_discrete(limits = order1) + labs(x = NULL) + theme_classic() + theme(legend.position = "none")
示例数据:
structure(list(category = c("points", "points", "points", "points", "points", "points", "points", "points", "points", "points", "points", "points"), var = c("Total", "Weak", "Strong", "White", "Black", "Hispanic", "Springfield", "Buxton", "Artowne", "Friedsville", "Alexandria", "Oldmill"), mean = c(175, 145, 160, 120, 200, 200, 225, 200, 100, 160, 120, 100), lower = c(156, 120, 140, 100, 168, 141, 191, 72, 45, 130, 100, 40), upper = c(190, 176, 185, 150, 245, 240, 280, 340, 230, 200, 150, 150)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -12L))
解决方案
可以通过插入空X轴水平实现组间空白,结合annotate添加组标签来实现需求,具体步骤如下:
- 调整X轴顺序,插入空水平
在原始的order1中插入空字符串作为组间隔,让X轴自动留出空白:
# 插入空水平作为组间间隔 order1 <- c("Total", "", "Weak", "Strong", "", "White", "Black", "Hispanic", "", "Springfield", "Buxton", "Artowne", "Friedsville", "Alexandria", "Oldmill")
- 添加组标签并调整图表
使用annotate()在各组中心位置添加自定义标签,同时调整主题避免标签重叠:
library(ggplot2) # 加载数据 data <- structure(list(category = c("points", "points", "points", "points", "points", "points", "points", "points", "points", "points", "points", "points"), var = c("Total", "Weak", "Strong", "White", "Black", "Hispanic", "Springfield", "Buxton", "Artowne", "Friedsville", "Alexandria", "Oldmill"), mean = c(175, 145, 160, 120, 200, 200, 225, 200, 100, 160, 120, 100), lower = c(156, 120, 140, 100, 168, 141, 191, 72, 45, 130, 100, 40), upper = c(190, 176, 185, 150, 245, 240, 280, 340, 230, 200, 150, 150)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -12L)) # 定义X轴顺序(含空水平) order1 <- c("Total", "", "Weak", "Strong", "", "White", "Black", "Hispanic", "", "Springfield", "Buxton", "Artowne", "Friedsville", "Alexandria", "Oldmill") # 绘制图表 data %>% ggplot(aes(y = mean, x = var, color = var)) + geom_point(size = 3) + geom_pointrange(aes(ymin = lower, ymax = upper)) + scale_x_discrete(limits = order1) + # 添加组标签,定位到各组中心位置 annotate("text", x = 3, y = min(data$lower) - 15, label = "Strength", size = 4, fontface = "bold") + annotate("text", x = 6.5, y = min(data$lower) - 15, label = "Race/Ethnicity", size = 4, fontface = "bold") + annotate("text", x = 12, y = min(data$lower) - 15, label = "City", size = 4, fontface = "bold") + labs(x = NULL, y = "Mean Value") + theme_classic() + theme( legend.position = "none", # 调整X轴标签上下间距,避免和组标签重叠 axis.text.x = element_text(margin = margin(t = 10)) )
- 代码说明
- 插入空水平:在
order1中加入空字符串,让X轴在组之间自动产生空白间隔 - 组标签定位:通过
x参数指定标签的X轴位置(对应调整后的order1索引,从1开始),y参数设置在所有数据点下方,避免遮挡 - 主题调整:通过
axis.text.x的margin参数调整X轴标签的上下间距,防止和组标签重叠
内容的提问来源于stack exchange,提问作者a_todd12
相关产品推荐
相关产品推荐

