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

添加Viridis配色后stat_slab柱状图消失的原因及解决方法

问题:添加fill映射后stat_slab柱状图消失的原因与修复

问题背景

使用ggdist、ggplot2和dplyr可视化有序数据,无配色的stat_slab代码可正常生成柱状图,但添加fill=factor(response)映射并使用Viridis配色后,柱状图消失。

数据结构示例

library(ggdist)
library(ggplot2)
library(dplyr)

data(long_data)

srss_question1 <- long_data %>%
  filter(type == "1") %>%
  dplyr::select(id, day, response)

head(srss_question1)
# A tibble: 6 × 3
     id day   response
  <dbl> <fct>    <dbl>
1     1 day7         5
2     1 day2         4
3     1 day0         3
4     2 day7         5
5     2 day2         5
6     2 day0         6

正常运行的无配色代码

srss_question1 %>%
  ggplot(aes(y = response, x = day)) +
  stat_slab(
    data = filter(srss_question1, day == "day7"),
    density = "histogram",
    breaks = breaks_fixed(width = 0.5),
    align = "center",
    position = position_nudge(x = 0),
    side = "right"
  ) +
  stat_slab(
    data = filter(srss_question1, day == "day2"),
    density = "histogram",
    breaks = breaks_fixed(width = 0.5),
    align = "center",
    position = position_nudge(x = 0),
    side = "right"
  ) +
  stat_slab(
    data = filter(srss_question1, day == "day0"),
    density = "histogram",
    breaks = breaks_fixed(width = 0.5),
    align = "center",
    position = position_nudge(x = 0),
    side = "right",
  ) +
  geom_line(
    aes(group = id),
    size = 0.25,
    position = position_jitter(h = 0.05, w = 0.05),
    alpha = 0.25
  ) +
  scale_y_continuous(limits = c(-0.25, 7.5), breaks = 0:10) +
  labs(x = "Day", y = "Question 1 Responses") +
  theme_bw()

添加fill映射后失效的代码

srss_question1 %>%
  ggplot(aes(x = day, y = response, fill = factor(response))) +
    stat_slab(
    data = filter(srss_question1, day == "day7"),
    density = "histogram",
    breaks = breaks_fixed(width = 0.5),
    align = "center",
    side = "right",
    position = position_nudge(x = 0)
  ) +      
    stat_slab(
    data = filter(srss_question1, day == "day2"),
    density = "histogram",
    breaks = breaks_fixed(width = 0.5),
    align = "center",
    side = "right",
    position = position_nudge(x = 0)
  ) +
    stat_slab(
    data = filter(srss_question1, day == "day0"),
    density = "histogram",
    breaks = breaks_fixed(width = 0.5),
    align = "center",
    side = "right",
    position = position_nudge(x = 0)
  ) +
    geom_line(
    aes(group = id),
    linewidth = 0.25,
    position = position_jitter(h = 0.05, w = 0.05),
    alpha = 0.25
  ) +
  scale_fill_viridis_d(option = "D", direction = 1) +
  scale_y_continuous(limits = c(-0.25, 7.5), breaks = 0:10) +
  labs(x = "Day", y = "Question 1 Responses") +
  theme_bw()

原因分析

  1. 分组冲突:全局映射fill = factor(response)后,ggplot会自动按response对数据分组。而stat_slab在density = "histogram"模式下,会基于分组计算直方图,导致每个分组仅包含单个response值的记录,无法形成有高度的柱状条,最终表现为柱状图消失。
  2. 冗余代码加剧问题:重复调用三次stat_slab分别处理不同day的逻辑,未覆盖全局分组映射,进一步导致每个day内的数据被拆分为多个极小分组,无法渲染出可见的柱状图。

修复方案

修复后代码

library(ggdist)
library(ggplot2)
library(dplyr)

srss_question1 <- long_data %>%
  filter(type == "1") %>%
  select(id, day, response)

srss_question1 %>%
  ggplot(aes(x = day, y = response)) +
  # 仅在stat_slab内部指定fill映射,并强制group=1避免按response分组
  stat_slab(
    aes(fill = factor(response), group = 1),
    density = "histogram",
    breaks = breaks_fixed(width = 0.5),
    align = "center",
    side = "right",
    position = position_nudge(x = 0)
  ) +
  geom_line(
    aes(group = id),
    linewidth = 0.25,
    position = position_jitter(h = 0.05, w = 0.05),
    alpha = 0.25
  ) +
  scale_fill_viridis_d(option = "D", direction = 1) +
  scale_y_continuous(limits = c(-0.25, 7.5), breaks = 0:10) +
  labs(x = "Day", y = "Question 1 Responses", fill = "Response") +
  theme_bw()

关键修复点

  • 将fill映射移至stat_slab内部:避免全局fill映射影响其他图层(如geom_line不需要fill),同时仅让直方图图层使用fill配色。
  • 添加group = 1:强制stat_slab按每个day的整体数据统计直方图,而非按response拆分分组,确保每个响应值的柱状条能显示对应的计数高度。
  • 简化代码:移除重复的三次stat_slab调用,利用ggplot的自动分组逻辑,基于x=day自动为每个day绘制直方图,代码更简洁易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 13:12:02