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

如何在R的ggplot2中连接偏移点图(dodged dotplots)中的配对点?

问题描述

我有多个变量进行了两次测量,希望绘制同时展示箱线图和个体数值(使用geom_dotplot)的图表,且同一变量的两次测量数值需用可自定义线条连接。我已找到使用抖动geom_point的解决方案(本质是生成新数据),但更希望使用点图(dotplot)。

以下是针对5个样本、2个变量的图表简化代码:

library(ggplot2)

dat <- data.frame(subject     = c(1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5), 
                  measurement = c("M1", "M1", "M1", "M1", "M1", "M2", "M2", "M2", "M2", "M2",
                                  "M1", "M1", "M1", "M1", "M1", "M2", "M2", "M2", "M2", "M2"), 
                  variable    = c("Var1", "Var1", "Var1", "Var1", "Var1", "Var1", "Var1", "Var1", "Var1", "Var1",
                                  "Var2", "Var2", "Var2", "Var2", "Var2", "Var2", "Var2", "Var2", "Var2", "Var2"), 
                  value       = c(20, 15, 21, 23, 15, 22, 21, 31, 24, 17, 26, 10, 23, 22, 19, 29, 15, 25, 29, 19))

ggplot(dat, aes(variable, value, colour = measurement)) +
  geom_boxplot(outlier.shape = NA) + 
  geom_dotplot(aes(fill = measurement),
               binaxis = "y", binwidth = 0.5, stackdir = "center", 
               position = position_dodge(0.75))

当前图表中,我希望连接同一变量内两次测量(M1与M2)的配对点,如Var1中手动绘制的线条所示:
当前图表

解决方案

要实现配对点的连接,核心是先提取geom_dotplot生成的点的实际坐标,再通过坐标匹配绘制连线,具体代码如下:

library(ggplot2)
library(dplyr)

# 原始数据
dat <- data.frame(subject     = c(1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5), 
                  measurement = c("M1", "M1", "M1", "M1", "M1", "M2", "M2", "M2", "M2", "M2",
                                  "M1", "M1", "M1", "M1", "M1", "M2", "M2", "M2", "M2", "M2"), 
                  variable    = c("Var1", "Var1", "Var1", "Var1", "Var1", "Var1", "Var1", "Var1", "Var1", "Var1",
                                  "Var2", "Var2", "Var2", "Var2", "Var2", "Var2", "Var2", "Var2", "Var2", "Var2"), 
                  value       = c(20, 15, 21, 23, 15, 22, 21, 31, 24, 17, 26, 10, 23, 22, 19, 29, 15, 25, 29, 19))

# 绘制基础图表并保存对象
p <- ggplot(dat, aes(variable, value, colour = measurement)) +
  geom_boxplot(outlier.shape = NA) + 
  geom_dotplot(aes(fill = measurement),
               binaxis = "y", binwidth = 0.5, stackdir = "center", 
               position = position_dodge(0.75))

# 提取dotplot图层的点坐标,匹配原始数据的分组信息
dot_data <- layer_data(p, 2) %>%
  mutate(
    measurement = rep(dat$measurement, each = 1),
    variable = rep(dat$variable, each = 1),
    subject = rep(dat$subject, each = 1)
  ) %>%
  # 按个体和变量分组,获取配对的M1/M2坐标
  group_by(subject, variable) %>%
  mutate(
    x_end = ifelse(measurement == "M1", x[measurement == "M2"], x[measurement == "M1"]),
    y_end = ifelse(measurement == "M1", y[measurement == "M2"], y[measurement == "M1"])
  ) %>%
  ungroup()

# 添加连线后的最终图表
p +
  geom_segment(
    data = dot_data %>% filter(measurement == "M1"),
    aes(x = x, xend = x_end, y = y, yend = y_end),
    colour = "gray50",  # 自定义线条颜色
    linetype = "dashed" # 自定义线条样式
  )

关键说明

  • layer_data(p, 2)用于提取第二个图层(即geom_dotplot)的点坐标,若图层顺序调整,需对应修改索引值
  • 通过rep将原始数据的分组信息映射到提取的坐标上,确保配对点匹配准确
  • 过滤measurement == "M1"的数据绘制连线,避免重复绘制同一组配对的线条

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 13:54:22