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

如何为ggalluvial绘制的Sankey图填充图案而非颜色?

问题:用图案而非颜色填充Sankey图的条形

我绘制了如下Sankey图,希望用图案而非不同颜色填充图中的条形。

Sankey图示例

该图基于以下可复现的数据框代码生成:

data <- data.frame(
  "ID"=rep(c(1:20),2), 
  "time"=c(rep(1,20),rep(2,20)), 
  "value"=c("B","G","B","G","B",rep("G",3),rep("B",2),"G",rep("B",3),"G",rep("B",6),"G","B","G","B",rep("G",3),rep("B",2),"G",rep("B",3),"G","B","switch",rep("B",2),"switch")
)

以下是绘制Sankey图的代码:

library(dplyr)
library(ggplot2)
library(ggalluvial)
library(ggpattern)

data %>% 
  group_by(time) %>% 
  mutate(w = n()) %>% 
  ggplot(aes(x = time, stratum = value, alluvium = ID,
             fill = value, label = value, y = 1/w)) +
  scale_x_discrete() +
  scale_y_continuous(name = "", label = scales::percent_format(accuracy = 1)) +
  geom_flow(stat = "flow", knot.pos = 1/4, aes.flow = "forward") +
  geom_stratum() +
  theme(legend.position = "bottom") +
  labs(x = "", fill = "")

我希望用图案而非不同颜色填充条形,尝试使用scale_pattern_type_manual(values=c('stripe', 'wave', 'wave', "crosshatch", "none","stripe", "crosshatch","none"))但并未生效。


解决方案

问题出在默认的geom_stratum不支持图案填充,需要改用ggpattern包提供的geom_stratum_pattern,同时正确设置图案映射和参数:

  1. 替换geom_stratum()为geom_stratum_pattern(aes(pattern = value)),将图案类型与value变量绑定
  2. 设置统一的填充色(如白色),避免颜色干扰图案显示
  3. 确保scale_pattern_type_manual的values数量与value的唯一类别数对应(先通过unique(data$value)确认类别:"B" "G" "switch")

修改后的完整代码:

library(dplyr)
library(ggplot2)
library(ggalluvial)
library(ggpattern)

data %>% 
  group_by(time) %>% 
  mutate(w = n()) %>% 
  ggplot(aes(x = time, stratum = value, alluvium = ID,
             label = value, y = 1/w)) +
  scale_x_discrete() +
  scale_y_continuous(name = "", label = scales::percent_format(accuracy = 1)) +
  # 流动部分设为统一灰色,避免颜色干扰
  geom_flow(stat = "flow", knot.pos = 1/4, aes.flow = "forward", fill = "gray80") +
  # 使用带图案的条形层,映射pattern到value,填充白色突出图案
  geom_stratum_pattern(aes(pattern = value), fill = "white") +
  # 为每个value指定对应的图案类型
  scale_pattern_type_manual(values = c("stripe", "wave", "crosshatch")) +
  theme(legend.position = "bottom") +
  labs(x = "", pattern = "")

这样就能实现用不同图案填充Sankey图的条形,替代原来的颜色区分。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 17:15:08