如何在R的ggplot2中创建间断Y轴?代码问题求助
用ggplot2实现带间断效果的Y轴
问题说明
需要在ggplot2中实现Y轴间断效果,当前效果与期望效果存在差异:
- 当前效果:Y轴间隙过大,无表示间断的斜线,底部分类文本被裁剪无法正常显示
- 期望效果:Y轴间隙紧凑,带有间断斜线,底部文本清晰显示,Y轴仅展示有效数据范围的刻度
解决方案代码
修改原代码,通过调整截断轴参数、添加斜线注释、优化绘图边距来解决问题:
library(ggplot2) library(dplyr) library(DescTools) library(ggh4x) library(grid) set.seed(321) # 生成数据 models <- c(1, 2, 3, 10, 11, 12) metrics <- c(1, 2, 3) n_repeats <- 144 dat <- expand.grid(model = models, metric = metrics) dat <- dat[rep(seq_len(nrow(dat)), n_repeats), ] dat$value <- rnorm(nrow(dat), 20, 4) dat2 <- data.frame(model = rep(13, 24), value = rnorm(24,10,.5), metric = rep(c(1,2,3),8)) df <- rbind(dat, dat2) %>% mutate(model = factor(model, levels = c("13", "1", "2", "3", "10", "11", "12")), metric = factor(metric)) desc.stats <- df %>% group_by(model, metric) %>% summarise(mean = mean(value), range.lower = range(value)[1], range.upper = range(value)[2], median = median(value), medianCI.lower = MedianCI(value, conf.level = 0.95, method = "exact", R = 10000)[2], medianCI.upper = MedianCI(value, conf.level = 0.95, method = "exact", R = 10000)[3]) %>% ungroup() desc.stats_filtered <- desc.stats %>% filter(model != 13) # 底部分类文本 text_high <- textGrob("主模型", gp=gpar(fontsize=12, fontface="bold")) text_low <- textGrob("次级模型", gp=gpar(fontsize=12, fontface="bold")) # 定义Y轴间断参数 y_gap_start <- 12 y_gap_end <- 17 # 缩小间隙:控制Y轴显示范围,跳过间隙区域 y_lower_range <- c(min(desc.stats$medianCI.lower), y_gap_start) y_upper_range <- c(y_gap_end, max(desc.stats$medianCI.upper)) ylim_total <- c(y_lower_range[1], y_upper_range[2]) p <- ggplot(desc.stats, aes(x=model, y=median, group=metric)) + geom_point(aes(shape=metric, colour = metric)) + geom_line(data = desc.stats_filtered, aes(colour = metric))+ scale_colour_manual(values = c("chocolate", "grey20", "blue")) + geom_errorbar(aes(ymin= medianCI.lower, ymax= medianCI.upper, colour = metric), width=.2) + theme_classic() + # 控制Y轴显示范围,压缩间隙 coord_cartesian(clip = "off", ylim = ylim_total) + # 添加底部分类文本和分隔线 annotation_custom(text_high, xmin=2, xmax=4, ymin= y_lower_range[1]-1, ymax= y_lower_range[1]-1) + annotation_custom(text_low, xmin=5, xmax=7, ymin= y_lower_range[1]-1, ymax= y_lower_range[1]-1) + annotate("segment", x = 0.5, xend = 3.4, y = y_lower_range[1]-0.8, yend = y_lower_range[1]-0.8) + annotate("segment", x = 3.6, xend = 7.5, y = y_lower_range[1]-0.8, yend = y_lower_range[1]-0.8) + # 添加Y轴间断斜线标记 annotate("segment", x = -0.15, xend = -0.25, y = y_gap_start + 0.2, yend = y_gap_end - 0.2) + annotate("segment", x = -0.25, xend = -0.15, y = y_gap_start + 0.2, yend = y_gap_end - 0.2) + # 调整主题边距,确保底部文本显示 theme(axis.title.x=element_blank(), plot.margin = unit(c(1,1,3,2), "lines"), axis.text.y = element_text(margin = margin(r=10))) + # 设置截断Y轴,隐藏间隙内的刻度 guides(y = guide_axis_truncated( trunc_lower = c(-Inf, y_gap_end), trunc_upper = c(y_gap_start, Inf) )) p
关键修改说明
- 缩小Y轴间隙:通过
coord_cartesian的ylim参数直接控制Y轴显示边界,跳过间隙区域,让图表上下数据区域更紧凑。 - 添加间断斜线:用
annotate("segment")绘制交叉斜线,明确标记Y轴的间断位置。 - 修复底部文本显示:增大绘图底部和左侧边距,调整文本的垂直位置,避免文本被裁剪。
- 优化截断轴:调整
guide_axis_truncated的截断范围,确保间隙内的刻度不被展示。
内容的提问来源于stack exchange,提问作者CatM
相关产品推荐
相关产品推荐

