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

如何用Stripplot展示Boxplot中的极端异常值?R语言求助

我来帮你解决这个箱线图异常值的展示问题!你的核心需求是在不隐藏异常值的前提下,让主图美观,同时把极端值单独展示,这个思路非常合理,下面我会一步步带你实现,还会修正你之前代码里的问题。

首先先梳理你之前代码里的几个小问题:

  • 拼写错误:df$Trail2应该是df$Trial2(少了一个字母i)
  • 异常值筛选逻辑有误:df[!(df %in% xout)]不能直接用在数据框上,因为xout是从多个分组提取的异常值集合,你需要针对每个分组(Trial2、Trial3)单独处理数据,同时保留分组信息。

方案实现:双图组合展示(主箱线图+异常值散点图)

我用ggplot2和tidyverse工具包来实现,它们能更灵活地处理数据和组合图表:

步骤1:准备数据与加载依赖包

先把你的示例数据加载好,同时把宽格式数据转成更适合分组处理的长格式:

# 加载必要的包(如果没安装先运行:install.packages("tidyverse"))
library(tidyverse)

# 示例数据(如果是从CSV读取,替换成 df <- read.csv("Inhibitor.csv", header=TRUE))
df <- tibble(
  Inhibitor = c("grak", "grab", "hhus", "hhuf", "kkul", "kkju", "juik", "jtui", "test"),
  Trial2 = c(0.20, 11.00, 0.21, 0.341, 1.66, 0.45, 0.30, 0.80, 0.233),
  Trial3 = c(0.45, 31.55, 0.18, 0.32, 0.80, 0.30, 0.20, 0.40, 0.36)
)

# 转成长格式,方便后续分组处理
df_long <- df %>%
  pivot_longer(cols = starts_with("Trial"), names_to = "Trial", values_to = "Rate")

步骤2:标记每个分组的异常值

用箱线图的默认规则(超过四分位距IQR的1.5倍)来识别异常值:

df_long <- df_long %>%
  group_by(Trial) %>%
  mutate(
    q1 = quantile(Rate, 0.25),
    q3 = quantile(Rate, 0.75),
    iqr = q3 - q1,
    # 标记是否为异常值
    is_outlier = Rate > q3 + 1.5*iqr | Rate < q1 - 1.5*iqr
  ) %>%
  ungroup()

步骤3:绘制主箱线图(y轴范围0-10)

主图只展示非异常值,同时隐藏默认的异常值点,避免干扰:

p_main <- ggplot(df_long %>% filter(!is_outlier | Rate <= 10), aes(x = Trial, y = Rate)) +
  geom_boxplot(fill = "#69b3a2", outlier.shape = NA) + # 隐藏默认异常值点
  geom_jitter(width = 0.2, alpha = 0.6) + # 添加非异常值散点,更直观展示数据分布
  ylim(0, 10) +
  labs(x = "Trial", y = "Rate") +
  theme_minimal()

步骤4:绘制上方的异常值散点图(y轴范围10-35)

这个图专门展示大于10的极端异常值,同时简化样式避免和主图重复:

p_outliers <- ggplot(df_long %>% filter(is_outlier & Rate > 10), aes(x = Trial, y = Rate)) +
  geom_point(color = "#ff4500", size = 3) + # 用醒目的橙色标记异常值
  ylim(10, max(df_long$Rate) + 2) + # y轴从10开始,留出一点空间
  labs(x = "", y = "") + # 去掉冗余的轴标签
  theme_minimal() +
  theme(
    axis.text.x = element_blank(), # 隐藏x轴刻度,和主图共用
    axis.ticks.x = element_blank(),
    panel.grid = element_blank() # 去掉网格线,保持简洁
  )

步骤5:组合两个图表

用patchwork包把两个图垂直组合,对齐x轴,设置合理的高度比例:

# 如果没安装patchwork,先运行:install.packages("patchwork")
library(patchwork)

# 异常值图在上,主图在下,高度比例2:8
p_outliers / p_main + plot_layout(heights = c(2, 8))

可选方案:截断箱线图+标记

如果你不想用两个图,也可以直接在主图里截断y轴,用箭头和文本标记异常值:

ggplot(df_long, aes(x = Trial, y = Rate)) +
  geom_boxplot(fill = "#69b3a2", outlier.shape = NA) +
  geom_jitter(data = df_long %>% filter(Rate <=10), width = 0.2, alpha = 0.6) +
  # 在y=10的位置用三角形标记异常值位置
  geom_point(data = df_long %>% filter(Rate >10), aes(x = Trial, y = 10), color = "#ff4500", shape = 2) +
  # 用箭头指向异常值实际位置
  geom_segment(data = df_long %>% filter(Rate >10), 
               aes(x = Trial, xend = Trial, y = 10, yend = 10), 
               arrow = arrow(length = unit(0.2, "cm")), color = "#ff4500") +
  # 标注异常值的具体数值
  annotate("text", x = df_long %>% filter(Rate >10) %>% pull(Trial), 
           y = df_long %>% filter(Rate >10) %>% pull(Rate),
           label = df_long %>% filter(Rate >10) %>% pull(Rate),
           vjust = -0.5, color = "#ff4500") +
  ylim(0, 10) +
  labs(x = "Trial", y = "Rate") +
  theme_minimal()

这样处理后,你的箱线图既保持了美观的展示效果,又完整保留了所有数据信息,不会因为极端值被压缩成线条啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:31:30