如何在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_
相关产品推荐
相关产品推荐

