如何镜像由半眼图、散点、箱线图组成的双组复合统计图
实现双组复合统计图的左右对称镜像布局
问题背景
已使用ggplot2绘制包含stat_halfeye、geom_jitter、geom_boxplot的双组(C、I组)复合统计图,当前效果满足需求,但需要将其修改为左右对称的镜像布局,让两组的密度半眼、箱线图和散点分别向两侧展开。
解决方案
核心是针对两组分别调整各图层的位置偏移方向,并设置stat_halfeye的显示方向,实现对称布局。以下是修改后的完整代码:
library(ggplot2) library(wesanderson) library(ggsignif) library(ggdist) # 数据准备 dat1 <- as.data.frame(c(175.070, 279.760, 310.120, 454.370, 356.190, 398.720, 394.790, 427.940, 450.090, 452.240, 344.630, 374.450, 401.810, 366.250, 455.150, 455.150, 284.820, 325.640, 437.840, 455.150, 455.150, 454.900, 433.970, 346.830, 455.050, 455.150, 448.740, 455.150, 455.000, 455.150, 243.920, 295.660, 282.430, 305.190, 368.580, 348.440, 437.100, 453.180, 454.100, 44.464, 420.280, 455.150, 427.250, 101.490, 454.100, 454.810, 323.690, 454.410, 235.160, 294.870, 455.150, 330.460, 289.610, 236.310, 454.810, 299.020, 29.289, 39.988, 348.340, 455.150, 439.540, 409.910, 440.310, 433.090, 455.150, 198.890, 454.100, 346.370, 261.780, 280.760, 427.180, 455.150, 233.740, 334.040, 452.240, 411.890, 378.310, 354.410, 347.670, 439.970)) colnames(dat1) = "value" dat1$group <- rep(c('C','I'), c(40, nrow(dat1)-40)) # 简化分组赋值,替代原循环 dat1$group <- factor(dat1$group, levels = c('C','I')) pltt <- rev(wes_palette(n=2, name="Darjeeling1")) # 绘制镜像对称图 p_mirrored <- ggplot(dat1, aes(x=group, y=value, color=group, fill=group)) + scale_fill_manual(values=pltt, guide = "none") + scale_color_manual(values=pltt, guide = "none") + # 为两组分别设置半眼方向和位置偏移 stat_halfeye( aes(side = ifelse(group == "C", "left", "right")), # C组左半眼,I组右半眼 adjust = .33, width = .6, alpha=0.3, position = position_nudge(x = ifelse(dat1$group == "C", -0.3, 0.3)) ) + # 散点分别向两侧偏移 geom_jitter( shape=16, alpha=0.5, position = position_jitter( width = ifelse(dat1$group == "C", -0.1, 0.1), height = 0 ) ) + # 箱线图分别向两侧偏移 geom_boxplot( width=0.05, outlier.shape = NA, fill=alpha(0.2), position = position_nudge(x = ifelse(dat1$group == "C", -0.2, 0.2)) ) + # 保持显著性标记位置不变 geom_signif( comparisons = list(c("C", "I")), tip_length = -0.01, y_position = -0.5, map_signif_level=TRUE, test="wilcox.test", color = "black" ) + ylim(0,460) + theme( legend.position = "none", axis.text=element_text(size=10), axis.title=element_text(size=12), plot.title = element_text(hjust = 0.5, size=14, face="bold") ) + theme_light() + ggtitle("Data distribution (Mirrored)") print(p_mirrored)
关键修改说明
- stat_halfeye:通过
side映射指定C组显示左半密度眼、I组显示右半密度眼,同时用position_nudge让两组的半眼分别向左右偏移 - geom_jitter:调整散点的抖动方向,让C组散点向左、I组向右,对应各自的半眼位置
- geom_boxplot:同样用
position_nudge让两组箱线图分别向左右偏移,保持与半眼的对齐 - 简化了原数据分组的赋值代码,去掉冗余循环
内容的提问来源于stack exchange,提问作者Unai Vicente
相关产品推荐
相关产品推荐

