You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 15:55:56