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

R语言绘制Beeswarm图出现异常空白间隙问题排查

问题描述

我用R语言遍历数据分组,为每个分组绘制Beeswarm图并合并成一张图,代码如下:

# 构建颜色映射函数
color.By.Category <- function(x) {
  if (x == "Polydrug") {
    return("red")
  } else if (x == "Opioid") {
    return("blue")
  } else if (x == "Cocaine") {
    return("green")
  } else if (x == "Gabapentin") {
    return("orange")
  } else if (x == "Meth") {
    return("blue")
  } else if (x == "Benzo") {
      return("pink")
  } else {
    return("black")
  }
}

# 设置画布布局:5行1列,第一行放图例
par(mfrow=c(5,1), mar=c(0,10,0,0), oma=c(10,0,5,2), bg="black")

# 绘制图例
drug.categories <- unique(death.data.2$drug)
colr <- sapply(drug.categories, color.By.Category)
xleg <- seq(-10,110, by=23)
beeswarm(xleg, pwcol=colr, 
         horizontal = TRUE, 
         pch=15, 
         method="center", 
         cex=1, 
         xlim=c(-10,110), 
         ylim=c(-10,4))
text(x=xleg, y=.5, labels=toupper(drug.categories), col="white", pos=4, cex=1.1)

# 按种族分组绘制蜂群图
races <- unique(death.data.2$race)
for (i in 1:length(races)) {
  # 筛选当前种族的数据
  current <- death.data.2[death.data.2$race == races[i],]
  # 绘制蜂群图
  beeswarm(current$age, pwcol=current$color,
           pch=15, method="center",
           cex=1, horizontal=TRUE,
           ylim=c(-10,10), xlim=c(0,100), axes=FALSE)
  # 添加种族标签
  mtext(races[i], side = 2, las=1, col="white", cex=.9)
}

# 添加X轴
x <- seq(0, 100, 5)
axis(side = 1, labels = x, at=x, col="black", col.ticks = "white")
mtext(x, side = 1, outer=FALSE, at=x, line=.8, col="white", cex=.8)
mtext("Age", side=1, at=x[1], outer=FALSE, col="white", line=2, adj=0.05, padj=.5, cex=.8)

# 添加标题
mtext("Overdose Deaths by Substance Type", side=3, outer=TRUE, line=1, cex=1.5, col="white")

生成的图里有奇怪的空白间隙(无数据显示的空白区域),看起来像绘图渲染的伪影,这是什么原因?


原因分析与解决办法

核心原因:beeswarm的center排列算法导致

你用了method="center"参数,这个算法会把相同数值的点严格居中对齐。如果某个年龄的点数量少,相邻年龄的点数量多,算法为了保持居中,会在稀疏点和密集点之间留出额外空间,就形成了视觉上的空白间隙——这不是渲染伪影,是算法特性导致的。

其他影响因素

  • ylim设置过大:每个蜂群图的ylim=c(-10,10)范围太大,实际蜂群只需要很小的纵向空间,过大的范围会让点的分布看起来更分散,放大了间隙的视觉效果。
  • 数据本身的分布:如果某个种族的年龄数据本身就存在连续缺失的区间(比如某个年龄段完全没有死亡案例),也会出现真实的空白,但从图来看更偏向算法导致的间隙。

解决办法

  1. 更换排列算法:把method="center"换成method="swarm"或method="hex",这两种算法会更紧凑地排列点,减少不必要的间隙:
    beeswarm(current$age, pwcol=current$color,
             pch=15, method="swarm",  # 替换为swarm或hex
             cex=1, horizontal=TRUE,
             ylim=c(0,2),  # 缩小纵向范围到合理值
             xlim=c(0,100), axes=FALSE)
    
  2. 缩小ylim范围:根据实际点的分布设置纵向范围,比如ylim=c(0,2),让点的排列更紧凑,弱化间隙的视觉感受。
  3. 检查数据分布:用table(current$age)查看每个种族的年龄分布,确认是否是真实的数据缺失;如果是算法导致的,直接用前两种方法调整即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 08:15:40