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

ggplot2叠加小提琴图时部分箱线图与散点未显示的问题求助

ggplot2叠加小提琴图时部分箱线图与散点未显示的问题求助

您好!我来帮您分析一下这个问题:

问题原因

您当前的代码里,每次添加geom_violin时都指定了新的y映射(比如y = Wrist、y = Tip_of_middle_finger),但紧接着的geom_boxplot和geom_jitter没有同步更新y的映射,它们依然沿用了最初ggplot定义的aes(Time, Elbow)里的Elbow作为y轴数据,所以只有第一个小提琴图(Elbow)上显示了箱线图和散点,后面的Wrist、Tip对应的箱线和散点其实是画在Elbow的y值位置上,自然看不到啦。

解决方案

推荐把数据转换成**长格式(tidy data)**来绘图,这是ggplot2最适配的数据结构,能避免重复写冗余的图层代码,也更不容易出错:

步骤1:转换数据格式

先用tidyr包的pivot_longer把宽数据转成长数据,把三个部位的数值整合到一列,同时新增一列标记部位名称:

library(ggplot2)
library(ggbreak)
library(tidyr) # 需要加载这个包做数据重塑

# 假设您的fakebis数据已经存在
data <- fakebis %>%
  pivot_longer(
    cols = c(Elbow, Wrist, `Tip of middle finger`),
    names_to = "Body_Part",
    values_to = "Position"
  )

positions <- c("Pre", "Post")

步骤2:绘制图形

现在只需要一次调用geom_violin、geom_boxplot、geom_jitter,用Body_Part映射颜色,就能在每个Time(Pre/Post)位置上叠加三个部位的图形:

p <- ggplot(data, aes(x = Time, y = Position, colour = Body_Part)) +
  theme_classic() +
  xlab("Measurement time relative to tool-use session") +
  scale_x_discrete(limits = positions) +
  scale_y_break(c(4, 27)) +
  ylab("Reported position (cm)") +
  # 叠加小提琴图,用position_dodge让多个图形横向对齐
  geom_violin(alpha = .5, size = 2, trim = FALSE, position = position_dodge(width = 0.8)) +
  # 叠加箱线图,和小提琴图的dodge宽度保持一致
  geom_boxplot(width = 0.1, position = position_dodge(width = 0.8)) +
  # 叠加散点,用jitterdodge实现散点分散且对齐
  geom_jitter(shape = 16, position = position_jitterdodge(jitter.width = 0.2, dodge.width = 0.8))

p

如果坚持用宽格式绘图(不推荐)

您需要给每个geom_boxplot和geom_jitter都明确指定对应的y值,比如:

# 初始代码修改版
p <- ggplot(data, aes(Time, Elbow))+
  theme_classic() +
  xlab("Measurment time relative to tool-use session")+
  scale_x_discrete(limits = positions)+
  scale_y_break(c(4, 27))+
  ylab("Reported position (cm)")

# Elbow的图层
p <- p + geom_violin(aes(colour = "1"), alpha = .5, size=2,trim=FALSE)+
  geom_boxplot(width=0.1)+
  geom_jitter(shape=16, position=position_jitter(0.2))

# Wrist的图层,每个geom都指定y=Wrist
q <- p + geom_violin(aes(y = Wrist, colour = "2"), alpha = .5, size=2,trim=FALSE)+
  geom_boxplot(aes(y = Wrist), width=0.1)+
  geom_jitter(aes(y = Wrist), shape=16, position=position_jitter(0.2))

# Tip的图层,每个geom都指定y=Tip_of_middle_finger
q <- q + geom_violin(aes(y = Tip_of_middle_finger, colour = "3"), alpha = .5, size=2,trim=FALSE)+
  geom_boxplot(aes(y = Tip_of_middle_finger), width=0.1)+
  geom_jitter(aes(y = Tip_of_middle_finger), shape=16, position=position_jitter(0.2))

q

不过这种方式代码冗余度高,后期修改也麻烦,还是更推荐用长格式的方法哦!

备注:内容来源于stack exchange,提问作者Ishan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 13:37:59