ggplot中使用facet_grid后保留scale_x_discrete刻度标签的问题
解决ggplot分面后自定义x轴刻度标签失效的问题
未分面时,通过scale_x_discrete的自定义labels函数可将x轴刻度替换为对应class的车辆总数,但添加facet_grid(cols = vars(displ))分面后,该自定义标签失效,无法按分面显示对应class的样本数(期望刻度为2、3、2、2)。以下是两种可行解决方案:
方案1:修改ggplot构建对象自定义面板刻度标签
直接修改ggplot生成的底层对象,为每个分面单独设置x轴标签:
library(tidyverse) library(ggpubr) # 生成基础绘图对象 p3 <- mpg %>% filter(class %in% c("compact", "subcompact"), displ %in% c(2, 2.5)) %>% ggplot(aes(x = class, y = hwy, col = class)) + geom_violin() + geom_point() + facet_grid(cols = vars(displ)) + stat_compare_means(method = "t.test", comparisons = list(c("compact", "subcompact")), label = after_stat("p.signf")) + theme_bw() # 构建绘图结构 pb <- ggplot_build(p3) # 定义每个分面的目标刻度标签 target_labels <- list( c("2", "3"), # displ=2分面的x轴标签 c("2", "2") # displ=2.5分面的x轴标签 ) # 为每个面板替换刻度标签 for(i in seq_along(pb$layout$panel_params)) { pb$layout$panel_params[[i]]$x$labels <- target_labels[[i]] } # 重新生成绘图并展示 p3_fixed <- ggplot_gtable(pb) plot(p3_fixed)
方案2:提前计算样本数,用geom_text替代刻度标签
先预处理数据计算每个分面下class的样本数,再用文本图层替代原x轴刻度:
library(tidyverse) library(ggpubr) # 预处理数据,加入每个displ-class组合的样本数 plot_data <- mpg %>% filter(class %in% c("compact", "subcompact"), displ %in% c(2, 2.5)) %>% left_join( mpg %>% filter(class %in% c("compact", "subcompact"), displ %in% c(2, 2.5)) %>% count(displ, class, name = "total_cars"), by = c("displ", "class") ) # 绘图 p3 <- ggplot(plot_data, aes(x = class, y = hwy, col = class)) + geom_violin() + geom_point() + facet_grid(cols = vars(displ)) + stat_compare_means(method = "t.test", comparisons = list(c("compact", "subcompact")), label = after_stat("p.signf")) + theme_bw() + # 隐藏原x轴刻度标签 theme(axis.text.x = element_blank()) + # 添加自定义样本数标签,放在x轴下方 geom_text(aes(label = total_cars, y = min(hwy) - 2), stat = "unique", # 每个class仅显示一次标签 color = "black") + # 扩展y轴范围,避免标签被截断 expand_limits(y = min(plot_data$hwy) - 3) p3
内容的提问来源于stack exchange,提问作者JMarchante
相关产品推荐
相关产品推荐

