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

ggdist stat_slab使用coord_cartesian设置x轴上限时填充丢失问题求助

问题描述

我尝试使用ggdist的stat_slab绘制brms模型的预测抽样结果,使用coord_cartesian放大坐标轴时遇到异常:调整x轴下限裁剪完全正常,比如把xlim下限从0调整到50时ggdist对象显示正常;但设置x轴上限时(例如从2000调整为1000),尾部超出x轴上限的stat_slab填充色会消失,看起来coord_cartesian对分布上侧的裁剪逻辑存在异常。

可复现问题的代码如下:

theme_set(theme_tidybayes() + panel_border())

set.seed(1)
vars = data.frame(year = rep(c("before","after"), each = 1100),
           treatment = rep(c("low","high","low","high"), each = 550))
dat = data.frame(vars, .value = rgamma(nrow(vars),
                                                    scale = 100, shape = 4))
ggplot(dat, 
       aes(x = .value, y = treatment, group= year, fill=year, color = year)) +
  stat_slab(alpha=0.6, slab_color = "black") + 
  #coord_cartesian(xlim = c(0, 2000)) +  # 完整数据显示正常
  #coord_cartesian(xlim = c(300, 2000)) +  # 裁剪下限正常
  #coord_cartesian(xlim = c(0, 1000))  + # 此时已有1个slab填充消失
  coord_cartesian(xlim = c(0, 900)) -> reprex1 # 此时3个slab填充消失

我实际绘图时需要设置slab_color=NA,仅使用填充色结合自定义填充色阶展示结果,因此填充丢失的问题对我影响很大,目前没有找到解决方案。

补充说明

该问题还和R图形系统的绘图窗口大小有关,窗口或绘图区域越小,slab中保留填充的部分越多,不同尺寸的导出示例如下:

  • 大尺寸导出代码:
reprex1
tiff(paste0(getwd(),"/reprex1.tiff"), 
     res=600, compression="lzw",
     height = 9, width = 13, units = "in")
print(reprex1)
dev.off()

大尺寸导出时所有slab的填充都会消失。

  • 小尺寸导出代码:
reprex1
tiff(paste0(getwd(),"/reprex1.tiff"), 
     res=600, compression="lzw",
     height = 3, width = 5, units = "in")
print(reprex1)
dev.off()

小尺寸导出时已有2个slab可以保留填充。

环境信息

使用的环境为R 4.1.0 (2021-05-18)、ggdist 2.4.1、ggplot2 3.3.5,所有包均已更新到对应版本的最新版,在base R和RStudio中均能复现该问题。

需求说明

原始数据方差较大,slab的尾部非常长,直接展示很难观察年份和处理组的均值差异,因此必须对绘图进行放大以聚焦高密度区域。


问题原因及解决方案

原因

这个是ggdist 2.x版本的已知兼容性问题:stat_slab默认的密度估算和多边形绘制逻辑和ggplot2的坐标裁剪规则适配存在缺陷。当密度多边形的大部分顶点落在coord_cartesian设置的显示范围外时,R底层图形设备会判定填充区域无效,绘图尺寸越大,密度采样的顶点数量越多,越容易触发这个判定,因此大尺寸导出时填充会完全消失。

解决方案

  1. 优先方案:升级ggdist到3.0及以上版本
    该版本已经官方修复了裁剪适配问题,升级后直接运行原有代码即可正常显示裁剪后的slab填充。

  2. 无法升级包的临时修复方案
    可以手动调整stat_slab的参数避免触发异常,两种可选参数设置:

  • 关闭自动截断,指定密度绘制范围:
ggplot(dat, 
       aes(x = .value, y = treatment, group= year, fill=year, color = year)) +
  stat_slab(alpha=0.6, slab_color = "black", trim = FALSE, cut = 0) + 
  coord_cartesian(xlim = c(0, 900))
  • 提前过滤超出显示范围的极端值,再绘图:
# 过滤掉不需要展示的上侧尾部数据
dat_filtered <- dat[dat$.value <= 900, ]

ggplot(dat_filtered, 
       aes(x = .value, y = treatment, group= year, fill=year, color = year)) +
  stat_slab(alpha=0.6, slab_color = "black") + 
  coord_cartesian(xlim = c(0, 900))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 00:33:03