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

如何在R语言中将箱线图正确嵌入小提琴图内?

解决ggplot2中小提琴图与箱线图不对齐的问题

问题场景

在R语言中使用ggplot2绘制小提琴图与箱线图的组合可视化时,出现箱线图未与小提琴图对齐的情况,相关数据集和原代码如下:

数据集

data = structure(list(Sample.ID = c("S-1", "S-2", "S-3", "S-4", "S-5", 
"S-6", "S-7", "S-8", "S-9", "S-10", "S-11", "S-12", "S-13", "S-1", 
"S-2", "S-3", "S-4", "S-5", "S-6", "S-7", "S-8", "S-9", "S-10", 
"S-11", "S-12", "S-13"), Season = structure(c(2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L), .Label = c("Summer", "Winter"), class = "factor"), 
    D.N = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 
    1L), .Label = c("Day", "Night"), class = "factor"), Tide.type = structure(c(3L, 
    1L, 2L, 2L, 1L, 3L, 3L, 3L, 1L, 2L, 2L, 1L, 3L, 1L, 2L, 2L, 
    2L, 3L, 3L, 3L, 1L, 2L, 2L, 1L, 3L, 3L), .Label = c("Flat", 
    "High", "Low"), class = "factor"), MPs..items.m3. = c(134, 
    144, 154, 156, 142, 122, 114, 148, 146, 152, 112, 108, 104, 
    224, 212, 100, 141.3333333, 193.3333333, 157.3333333, 129.3333333, 
    146.6666667, 188, 93.33333333, 210.6666667, 122.6666667, 
    114.6666667)), row.names = c(NA, -26L), class = "data.frame")

原代码

data$Season = as.factor(data$Season)
data$D.N = as.factor(data$D.N)
data$Tide.type = as.factor(data$Tide.type)
str(data)

library(ggplot2)

ggplot(data, aes(x=Season, y=MPs..items.m3.)) +
  geom_violin(aes(fill = D.N),)+
  geom_boxplot(aes(fill = D.N), width = 0.2)

问题原因

使用fill进行分组时,geom_violin默认会将同一x轴类别下的分组小提琴图以width=0.9的间距并排展示,但geom_boxplot的默认分组位置没有匹配这个间距,导致两者错位。

修正方案

为geom_boxplot添加position = position_dodge(width = 0.9)参数,同时显式指定geom_violin的位置参数(与箱线图保持一致),即可让两者的分组完全对齐。

修正后的代码

data$Season = as.factor(data$Season)
data$D.N = as.factor(data$D.N)
data$Tide.type = as.factor(data$Tide.type)
str(data)

library(ggplot2)

ggplot(data, aes(x=Season, y=MPs..items.m3.)) +
  geom_violin(aes(fill = D.N), position = position_dodge(width = 0.9)) +
  geom_boxplot(aes(fill = D.N), width = 0.2, position = position_dodge(width = 0.9))

可选优化

如果想提升可视化清晰度,避免箱线图被小提琴图覆盖,可以添加半透明效果和箱线图边框:

ggplot(data, aes(x=Season, y=MPs..items.m3.)) +
  geom_violin(aes(fill = D.N), position = position_dodge(width = 0.9), alpha = 0.7) +
  geom_boxplot(aes(fill = D.N), width = 0.2, position = position_dodge(width = 0.9), color = "black")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 13:42:52