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

使用facet_grid2自由刻度时如何保持箱线图图案一致性?

问题

我有一个包含两个实验区域不同处理组质量的数据集:其中一个区域有2种处理,另一个区域有4种处理,且两个区域的数值差异较大。我希望通过facet_grid2()(来自ggh4x包)绘制图形,实现两个需求:

  • 离散x轴采用自由刻度,使两个分面中的箱线图尺寸一致,分面宽度随处理数量变化;
  • 连续y轴采用自由刻度,适配区域间的数值差异。

目前已通过ggh4x实现上述刻度设置,但发现设置x轴自由刻度后,较窄分面中箱线图的条纹间距变小——即使手动指定了图案参数,需要保持箱线图的图案(条纹间距等)在两个分面中一致。

当前代码:

# generate data
treat1 <- c(rep("bare",10), rep("veg",10), rep("bare",10), rep("veg",10), rep("bare",10), rep("veg",10))
treat2 <- c(rep("wet",10), rep("wet",10), rep("wet",10), rep("wet",10), rep("dry",10), rep("dry",10))
area <- c(rep("down",10), rep("down",10), rep("up",10), rep("up",10), rep("up",10), rep("up",10))
weight <- c(runif(10, 20, 50), runif(10, 1, 15), runif(10, 1, 10), runif(10, 1, 5), runif(10, 1, 10), runif(10, 1, 5))

dat_exp <- tibble("treat1" = treat1, "treat2" = treat2, "area" = area, "mass" = weight) %>%
  mutate(treat2_area = paste(treat2, area, sep = "."),
         treat1_treat2 = paste(treat1, treat2, sep = "."))


# plot it

ggplot(data = dat_exp, aes(x= treat1_treat2, y = mass, fill = treat2_area, pattern = treat1)) +
  theme_bw() +
  geom_boxplot_pattern(position = position_dodge(preserve = "single"), color = "black", pattern_colour = "white", pattern_fill = "white", pattern_angle = 45, pattern_density = 0.3, pattern_spacing = 0.025, pattern_key_scale_factor = 0.6) +
  scale_pattern_manual(values = c(bare = "stripe", veg = "none")) +
  ggh4x::facet_grid2(. ~ area, space = "free_x", scales = "free", independent = "y", switch = "both")

问题现象:较窄分面(如down区域)的箱线图条纹间距明显小于较宽分面(up区域),即使指定了pattern_spacing参数。

解决方案

核心问题是geom_boxplot_pattern的图案参数默认基于绘图面板的相对尺寸计算,分面宽度不同时,相同参数会被缩放到不同实际大小。解决方法是将图案间距的单位设置为数据坐标(native),让条纹间距基于箱线图的实际宽度而非面板比例。

修改后的代码:

# generate data
treat1 <- c(rep("bare",10), rep("veg",10), rep("bare",10), rep("veg",10), rep("bare",10), rep("veg",10))
treat2 <- c(rep("wet",10), rep("wet",10), rep("wet",10), rep("wet",10), rep("dry",10), rep("dry",10))
area <- c(rep("down",10), rep("down",10), rep("up",10), rep("up",10), rep("up",10), rep("up",10))
weight <- c(runif(10, 20, 50), runif(10, 1, 15), runif(10, 1, 10), runif(10, 1, 5), runif(10, 1, 10), runif(10, 1, 5))

dat_exp <- tibble("treat1" = treat1, "treat2" = treat2, "area" = area, "mass" = weight) %>%
  mutate(treat2_area = paste(treat2, area, sep = "."),
         treat1_treat2 = paste(treat1, treat2, sep = "."))


# plot it with consistent pattern spacing
ggplot(data = dat_exp, aes(x= treat1_treat2, y = mass, fill = treat2_area, pattern = treat1)) +
  theme_bw() +
  geom_boxplot_pattern(
    position = position_dodge(preserve = "single"), 
    color = "black", 
    pattern_colour = "white", 
    pattern_fill = "white", 
    pattern_angle = 45, 
    pattern_density = 0.3, 
    pattern_spacing = 0.2,  # 根据箱线图宽度调整数值
    pattern_spacing_unit = "native",  # 关键:使用数据坐标单位
    pattern_key_scale_factor = 0.6
  ) +
  scale_pattern_manual(values = c(bare = "stripe", veg = "none")) +
  ggh4x::facet_grid2(. ~ area, space = "free_x", scales = "free", independent = "y", switch = "both")

关键修改说明

  • 添加pattern_spacing_unit = "native":将条纹间距的计算基准从面板相对尺寸改为数据坐标,确保不同分面中箱线图的条纹间距一致。
  • 调整pattern_spacing数值:因为单位改为数据坐标,原有的小数值会显得过大,需根据实际箱线图宽度调整为合适值(示例中用0.2)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:57:07