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

使用scale_y_break后,如何修改R中y轴标签且避免双轴显示

问题:拆分Y轴后如何避免双Y轴标签重复显示

我拥有两组基线百分比变化(Percentage Change from Baseline)数据,为可视化数据绘制了箱线图,并通过stat_summary在底部添加了观测数量。此外,还开展了Wilcoxon检验,评估每组的基线百分比变化与0是否存在显著差异。

尝试将Y轴拆分为两部分后,使用scale_y_continuous修改Y轴标签时遇到问题:Y轴在左右两侧重复显示标签。希望在不显示双轴的前提下修改Y轴标签。


原始数据与代码

set.seed(200)
# 数据
df <- data.frame(
  G1 = c(rep("A", 8), rep("B", 30)),
  G2 = c(rnorm(8, mean = 2, sd = 10), rnorm(29, mean = 50, sd = 20), 1000)
)

n_fun <- function(x){
  return(data.frame(y = min(df$G2) * 5, # 调整位置
                    label = paste("N=", length(x), "\n")))
  
}

library(dplyr)
# 按组计算均值和标准差
mean_sd <- df %>% 
  group_by(G1) %>% 
  summarize(
    rmean = mean(G2),
    rsd = sd(G2)
  )
# ____ 箱线图绘制: 
theme_set(theme_minimal())

# 检验每组与0的差异
WC_tests = df %>%
  group_by(G1) %>%
  summarise(P = wilcox.test(G2, mu = 0)$p.value,
            Sig = if (P <= 0.0001) {
              "****"} else if (P <= 0.001) {
              "***" } else if (P <= 0.01) {
              "**"  } else if (P <= 0.05) {
              "*"   } else {
              "ns"  },
            MaxWidth = max(G2))

# 绘图
ggboxplot(df, x = "G1", y = "G2", color = "G1", add = "jitter", palette = "jco") +
  # 坐标轴与图例
  xlab("") + 
  ylab("Percent Change") +
  theme(legend.key.size = unit(2.5, "lines")) +
  scale_y_break(c(100, 980)) + # 拆分Y轴
  scale_y_continuous(breaks = c(0,50,100, 980, 1000), labels = c(0,50,100, 980, 1000)) + 
  theme(axis.text.x = element_text(angle = 0, size = 9),
        axis.text.y = element_text(size = 10),
        # 移除右侧刻度文本
        axis.text.y.right = element_blank()) +
  
  # 样本量
  stat_summary(fun.data = n_fun, geom = "text",
               aes(group = G1), hjust = 0.8,
               position = position_dodge(0.9), size = 3) +
  
  # Wilcoxon检验显著性标注
  geom_text(aes(label = Sig, y = max(df$G2) + 3), size = 3,
            data = WC_tests)+
  # 添加0值参考线
  geom_hline(yintercept = 0, linetype = "dashed", color = "gray") +
  
  # 标注均值与标准差
  geom_text(data = mean_sd, aes(x = G1, y = 990,
                                label = paste("Mean(SD):",
                                              round(rmean, 2),
                                              "(",
                                              round(rsd, 2),
                                              ")")),
            color = "black")

原始效果图

双Y轴重复标签示意图1
双Y轴重复标签示意图2


解决方案

问题出在scale_y_break()(来自ggbreak包)默认会生成右侧Y轴,导致标签和刻度重复。可通过以下两种方式解决:

方法1:隐藏右侧Y轴所有元素

在theme()中补充参数,彻底隐藏右侧Y轴的标题、刻度和文本:

theme(
  axis.text.x = element_text(angle = 0, size = 9),
  axis.text.y = element_text(size = 10),
  axis.text.y.right = element_blank(), # 移除右侧刻度文本
  axis.title.y.right = element_blank(), # 移除右侧Y轴标题
  axis.ticks.y.right = element_blank() # 移除右侧Y轴刻度
)

方法2:直接关闭右侧Y轴

在scale_y_break()中设置right_axis = FALSE,直接不生成右侧Y轴:

scale_y_break(c(100, 980), right_axis = FALSE) # 拆分Y轴并关闭右侧轴

修改后的完整代码

set.seed(200)
# 数据
df <- data.frame(
  G1 = c(rep("A", 8), rep("B", 30)),
  G2 = c(rnorm(8, mean = 2, sd = 10), rnorm(29, mean = 50, sd = 20), 1000)
)

n_fun <- function(x){
  return(data.frame(y = min(df$G2) * 5, # 调整位置
                    label = paste("N=", length(x), "\n")))
  
}

library(dplyr)
library(ggpubr) # 加载ggboxplot所在包
library(ggbreak) # 加载scale_y_break所在包
# 按组计算均值和标准差
mean_sd <- df %>% 
  group_by(G1) %>% 
  summarize(
    rmean = mean(G2),
    rsd = sd(G2)
  )
# ____ 箱线图绘制: 
theme_set(theme_minimal())

# 检验每组与0的差异
WC_tests = df %>%
  group_by(G1) %>%
  summarise(P = wilcox.test(G2, mu = 0)$p.value,
            Sig = if (P <= 0.0001) {
              "****"} else if (P <= 0.001) {
              "***" } else if (P <= 0.01) {
              "**"  } else if (P <= 0.05) {
              "*"   } else {
              "ns"  },
            MaxWidth = max(G2))

# 绘图
ggboxplot(df, x = "G1", y = "G2", color = "G1", add = "jitter", palette = "jco") +
  # 坐标轴与图例
  xlab("") + 
  ylab("Percent Change") +
  theme(legend.key.size = unit(2.5, "lines")) +
  scale_y_break(c(100, 980), right_axis = FALSE) + # 拆分Y轴并关闭右侧轴
  scale_y_continuous(breaks = c(0,50,100, 980, 1000), labels = c(0,50,100, 980, 1000)) + 
  theme(axis.text.x = element_text(angle = 0, size = 9),
        axis.text.y = element_text(size = 10)) +
  
  # 样本量
  stat_summary(fun.data = n_fun, geom = "text",
               aes(group = G1), hjust = 0.8,
               position = position_dodge(0.9), size = 3) +
  
  # Wilcoxon检验显著性标注
  geom_text(aes(label = Sig, y = max(df$G2) + 3), size = 3,
            data = WC_tests)+
  # 添加0值参考线
  geom_hline(yintercept = 0, linetype = "dashed", color = "gray") +
  
  # 标注均值与标准差
  geom_text(data = mean_sd, aes(x = G1, y = 990,
                                label = paste("Mean(SD):",
                                              round(rmean, 2),
                                              "(",
                                              round(rsd, 2),
                                              ")")),
            color = "black")

内容的提问来源于stack exchange,提问作者Ph.D.Student

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 23:48:09