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

ggplot2绘制分组小提琴图异常,如何正确展示连续变量分布?

解决小提琴图绘制异常的问题

问题背景

尝试用以下代码基于取值范围1-5的var_y变量为两个分组绘制小提琴图:

p <- ggplot(df, aes(var_group, var_y))
p + geom_violin()

图表显示异常,疑似数据未正确绘制或变量未被识别为连续变量。已执行df$var_y <- as.numeric(as.character(df$var_y))确保变量为数值型,但问题仍未解决。使用另一取值范围1-10的原生数值变量按相同方法绘制的小提琴图显示正常,因此对当前图表存在疑问,希望能清晰展示变量整体分布的小提琴图。

数据集为长格式,每个id对应70条记录,完整数据集约4200行,样本数据如下:

df <- structure(list(id = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2), var_group = c("A", "A", "A", "A", "A", "A", "A", "A", "A", 
"A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", 
"A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", 
"A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", 
"A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", 
"A", "A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", 
"B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", 
"B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", 
"B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", 
"B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", 
"B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B"), var_y = c(3, 4, 5, 2, 3, 3, 2, 2, 3, 4, 2, 2, 3, 4, 5, 
4, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 3, 4, NA, 4, 5, 
5, 3, 4, 2, 4, 4, 4, 4, NA, 4, 4, 4, 4, 4, NA, 3, NA, 4, 5, 4, 
NA, NA, 4, 5, 5, 3, NA, 4, 4, 4, 5, 5, 5, 4, 5, 1, 1, NA, NA, 
1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 
1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, NA, 2, 2, 
1, 1, 1, 1, NA, 2, 1, 1, 2, 1, 1, 1, 2, 1, 2, NA, 1, 1, 1, 2, 
1, 1, 1, 1, 1)), class = "data.frame", row.names = c(211L, 212L, 
213L, 214L, 215L, 216L, 217L, 218L, 219L, 220L, 221L, 222L, 223L, 
224L, 225L, 226L, 227L, 228L, 229L, 230L, 231L, 232L, 233L, 234L, 
235L, 236L, 237L, 238L, 239L, 240L, 241L, 242L, 243L, 244L, 245L, 
246L, 247L, 248L, 249L, 250L, 251L, 252L, 253L, 254L, 255L, 256L, 
257L, 258L, 259L, 260L, 261L, 262L, 263L, 264L, 265L, 266L, 267L, 
268L, 269L, 270L, 271L, 272L, 273L, 274L, 275L, 276L, 277L, 278L, 
279L, 280L, 421L, 422L, 423L, 424L, 425L, 426L, 427L, 428L, 429L, 
430L, 431L, 432L, 433L, 434L, 435L, 436L, 437L, 438L, 439L, 440L, 
441L, 442L, 443L, 444L, 445L, 446L, 447L, 448L, 449L, 450L, 451L, 
452L, 453L, 454L, 455L, 456L, 457L, 458L, 459L, 460L, 461L, 462L, 
463L, 464L, 465L, 466L, 467L, 468L, 469L, 470L, 471L, 472L, 473L, 
474L, 475L, 476L, 477L, 478L, 479L, 480L, 481L, 482L, 483L, 484L, 
485L, 486L, 487L, 488L, 489L, 490L))

问题原因与解决方案

原因分析

var_y是取值仅为1-5的离散数值型变量,小提琴图默认的核密度估计对这类离散数据的拟合效果很差,导致图形异常。而取值1-10的变量因为取值更分散,核密度估计能正常生成,所以图表显示正常。

解决方案

方案1:调整核密度估计的带宽

手动设置更小的带宽,让密度估计更贴合离散数据的分布:

library(ggplot2)

ggplot(df, aes(var_group, var_y)) +
  geom_violin(adjust = 0.5) +  # 调整adjust参数,值越小带宽越窄
  scale_y_continuous(breaks = 1:5)  # 显示所有1-5的刻度

方案2:结合箱线图或散点图展示离散分布

小提琴图对离散数据的表现力有限,建议叠加箱线图或散点图补充信息:

ggplot(df, aes(var_group, var_y)) +
  geom_violin(adjust = 0.5) +
  geom_boxplot(width = 0.1, fill = "white") +  # 叠加箱线图展示分位数
  scale_y_continuous(breaks = 1:5)

或者用散点图展示原始数据分布:

ggplot(df, aes(var_group, var_y)) +
  geom_jitter(width = 0.2, alpha = 0.3) +  # 抖动散点避免重叠
  geom_violin(alpha = 0.2, adjust = 0.5) +
  scale_y_continuous(breaks = 1:5)

方案3:改用更适合离散数据的图表

如果小提琴图不是必须的,可使用柱状图展示每个取值的频数分布:

ggplot(df, aes(var_y, fill = var_group)) +
  geom_histogram(binwidth = 1, position = "dodge") +
  facet_wrap(~var_group) +
  scale_x_continuous(breaks = 1:5)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 08:03:10