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

如何在ggplot截断Y轴外侧添加对角线标注截断(负象限可见)

解决方案:在截断Y轴的柱状图添加延伸至负象限的对角线

要实现你的需求——在Y轴截断处添加两条延伸至负象限的对角线,同时避免柱状图显示Y<300的部分,可以采用以下两种方法:


方法1:使用grid包直接添加线条(推荐)

这种方法保留原绘图的裁剪设置,确保柱状图下半部分不显示,同时通过grid包在绘图设备上直接绘制线条,不受ggplot面板限制。

完整代码

library(ggplot2)
library(tidyverse)
library(papaja)
library(grid)

# 创建数据
rt_val_summary <- tibble(
  Trialcount = c(1, 2, 3, 4, 5, 6, 7),
  Stimulus.ACC = c(0, 1, 0, 1, 0, 1, 0),
  N = c(1597, 47, 1019, 918, 278, 1655, 1019),
  Stimulus.RT = c(792.5792, 1061.4043, 929.4210, 910.0447, 1115.7986, 861.1704, 929.4210),
  sd = c(310.2690, 477.0400, 385.5723, 373.0941, 447.2075, 342.7538, 385.5723),
  se = c(7.764008, 69.583435, 12.078659, 12.313941, 26.821723, 8.425260, 12.078659),
  ci = c(15.22872, 140.06419, 23.70192, 24.16678, 52.80031, 16.52530, 23.70192)
)

# 绘制主图(保留Y轴截断,裁剪柱状图下半部分)
RT_val_plot <- ggplot(data=rt_val_summary, aes(x=Trialcount, y = Stimulus.RT, fill = factor(Stimulus.ACC))) +
  geom_bar(stat = "summary", position="dodge") +
  scale_x_continuous(breaks = c(1,2,3,4,5,6,7)) +
  labs(x = "Trial", y = "Reaction time (ms)") +
  coord_cartesian(ylim = c(300, 1200)) +
  scale_fill_manual(values=c("red", "green"),
                    name = "Valence", labels = c("negative", "positive")) +
  geom_errorbar(aes(ymin=Stimulus.RT-se, ymax=Stimulus.RT+se), width =.1, position=position_dodge(.9)) +
  geom_text(aes(label=paste("n =", N)), vjust=-0.5, position=position_dodge(0.9), size=3) +
  geom_point(size = 2 , position=position_dodge(.9)) +
  theme_apa()

# 打印主图
print(RT_val_plot)

# 定义数据坐标转npc坐标的函数
data_to_npc <- function(x, y, plot) {
  pp <- ggplot_build(plot)$layout$panel_params[[1]]
  x_npc <- scales::rescale(x, from = pp$x.range)
  y_npc <- scales::rescale(y, from = pp$y.range)
  data.frame(x = x_npc, y = y_npc)
}

# 设置对角线的起点和终点(数据坐标)
line1_start <- data_to_npc(0.8, 300, RT_val_plot)
line1_end <- data_to_npc(1.2, -200, RT_val_plot)

line2_start <- data_to_npc(0.8, 250, RT_val_plot)
line2_end <- data_to_npc(1.2, -250, RT_val_plot)

# 添加两条对角线
grid.lines(x = c(line1_start$x, line1_end$x), y = c(line1_start$y, line1_end$y), 
           gp = gpar(col = "black", lwd = 1))
grid.lines(x = c(line2_start$x, line2_end$x), y = c(line2_start$y, line2_end$y), 
           gp = gpar(col = "black", lwd = 1))

关键说明

  • coord_cartesian(ylim = c(300, 1200)) 确保柱状图Y<300的部分被裁剪,不会显示。
  • data_to_npc 函数将数据坐标转换为ggplot内部的归一化坐标(npc),方便精确定位线条。
  • grid.lines 直接在绘图设备上绘制线条,不受ggplot面板裁剪限制,因此可以延伸到负象限。

方法2:调整柱状图Y轴起始值 + annotation_custom

这种方法通过修改柱状图的Y轴起始值,配合clip="off"实现线条延伸,同时避免柱状图显示负区域。

完整代码

library(ggplot2)
library(tidyverse)
library(papaja)
library(grid)

# 创建数据
rt_val_summary <- tibble(
  Trialcount = c(1, 2, 3, 4, 5, 6, 7),
  Stimulus.ACC = c(0, 1, 0, 1, 0, 1, 0),
  N = c(1597, 47, 1019, 918, 278, 1655, 1019),
  Stimulus.RT = c(792.5792, 1061.4043, 929.4210, 910.0447, 1115.7986, 861.1704, 929.4210),
  sd = c(310.2690, 477.0400, 385.5723, 373.0941, 447.2075, 342.7538, 385.5723),
  se = c(7.764008, 69.583435, 12.078659, 12.313941, 26.821723, 8.425260, 12.078659),
  ci = c(15.22872, 140.06419, 23.70192, 24.16678, 52.80031, 16.52530, 23.70192)
)

# 绘制调整后的图
RT_val_plot <- ggplot(data=rt_val_summary, aes(x=Trialcount, y = Stimulus.RT - 300, fill = factor(Stimulus.ACC))) +
  geom_col(position="dodge") + # 用geom_col,Y值为相对300的高度
  scale_x_continuous(breaks = c(1,2,3,4,5,6,7)) +
  # 调整Y轴刻度标签,显示原数据数值
  scale_y_continuous(breaks = c(0, 200, 400, 600, 900), 
                     labels = c(300, 500, 700, 900, 1200)) +
  labs(x = "Trial", y = "Reaction time (ms)") +
  coord_cartesian(ylim = c(0, 900), clip = "off") + # 允许元素超出绘图面板
  scale_fill_manual(values=c("red", "green"),
                    name = "Valence", labels = c("negative", "positive")) +
  # 调整误差线的Y轴范围
  geom_errorbar(aes(ymin=(Stimulus.RT-se)-300, ymax=(Stimulus.RT+se)-300), 
                width =.1, position=position_dodge(.9)) +
  geom_text(aes(label=paste("n =", N)), vjust=-0.5, position=position_dodge(0.9), size=3) +
  geom_point(aes(y=Stimulus.RT-300), size = 2 , position=position_dodge(.9)) +
  theme_apa() +
  # 添加两条对角线
  annotation_custom(linesGrob(x = unit(c(0.8, 1.2), "npc"), 
                              y = unit(c(0, -0.5), "npc"), 
                              gp = gpar(lwd=1))) +
  annotation_custom(linesGrob(x = unit(c(0.8, 1.2), "npc"), 
                              y = unit(c(-0.05, -0.55), "npc"), 
                              gp = gpar(lwd=1))) +
  # 增加底部边距,确保线条完整显示
  theme(plot.margin = margin(b = 20, l = 20, unit = "pt"))

# 打印图
print(RT_val_plot)

关键说明

  • 将柱状图的Y值改为Stimulus.RT - 300,使柱子底部对齐原数据的300,不会延伸到负区域。
  • coord_cartesian(clip = "off") 允许annotation_custom的线条超出绘图面板范围。
  • 调整Y轴刻度标签,保持与原数据一致的显示逻辑。

内容的提问来源于stack exchange,提问作者nevial

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 20:14:55