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

如何用networkD3的sankeyNetwork处理客户组双向流动可视化难题

双向流动桑基图的优化与替代方案

一、解决桑基图双向流混乱的方法

对于networkD3的sankeyNetwork生成的双向流重叠、可读性差的问题,可以从数据处理和图表设置两个角度调整:

1. 合并双向流(按需选择)

如果你的分析重点是净流动趋势,而非双向各自的流动细节,可以直接计算两组间的净差值,只保留净流动的方向:

# 处理双向数据,计算净流量
links_processed <- links_2 %>%
  # 给双向配对打标签
  mutate(pair = ifelse(from < to, paste(from, to, sep = "-"), paste(to, from, sep = "-"))) %>%
  group_by(pair) %>%
  summarise(
    # 保留流量大的方向
    from = first(ifelse(value == max(value), from, to)),
    to = first(ifelse(value == max(value), to, from)),
    value = abs(diff(value))
  ) %>%
  ungroup() %>%
  select(-pair)

# 重新生成桑基图
p <- sankeyNetwork(Links = links_processed, Nodes = nodes_2,
                   Source = "from", Target = "to",
                   Value = "value", NodeID = "nodes",
                   fontSize=20)
p

这种方式会简化图表,但会丢失双向流动的细节,适合只看整体趋势的场景。

2. 调整桑基图布局减少重叠

networkD3的sinksRight参数默认是TRUE(强制所有终点在右侧),改成FALSE后节点可以左右分布,能缓解双向流的交叉:

p <- sankeyNetwork(Links = links_2, Nodes = nodes_2,
                   Source = "from", Target = "to",
                   Value = "value", NodeID = "nodes",
                   fontSize=20, sinksRight = FALSE)
p

如果需要更精细的控制,还可以手动修改底层D3代码调整节点的y坐标,但需要具备基础的JavaScript知识。

二、桑基图是否适合你的场景?

桑基图天生是用来展示单向流量传递路径的(比如用户从A到B到C的转化路径)。如果你的核心分析对象是双向流动(比如客户组之间的互相迁移),桑基图确实不是最优选择:

  • 双向流过多时,线条交叉会让图表变得杂乱,无法清晰呈现各组的互动关系。
  • 但如果双向流动只是少数情况,且你需要保留完整的流量路径,优化后的桑基图仍然可以使用。

三、替代工具推荐

如果双向流动是你的分析重点,试试这些工具:

1. 和弦图(最适配双向流动场景)

和弦图专门用于展示对称的双向/多向流动,完美匹配客户组之间的相互迁移分析,用circlize包即可实现:

library(circlize)

# 把数据转换为矩阵格式
flow_matrix <- matrix(c(0, 10, 20, 0), nrow = 2, byrow = TRUE,
                      dimnames = list(c("a", "b"), c("a", "b")))

# 绘制和弦图
chordDiagram(flow_matrix, annotationTrack = "grid", 
             preAllocateTracks = list(track.height = max(strwidth(unlist(dimnames(flow_matrix))))))

2. 分组条形图/热力图

如果更关注流动的数值大小而非路径关系,可以用分组条形图展示双向流量,或者热力图呈现组间流动的密集程度:

  • 分组条形图(基于ggplot2):
library(ggplot2)

links_2 %>%
  left_join(nodes_2, by = c("from" = "row_number")) %>%
  rename(source = nodes) %>%
  left_join(nodes_2, by = c("to" = "row_number")) %>%
  rename(target = nodes) %>%
  ggplot(aes(x = source, y = value, fill = target)) +
  geom_col(position = "dodge") +
  labs(title = "客户组双向流动规模")

3. 力导向图

如果组间关系复杂,还可以用力导向图展示节点间的双向连接,线条粗细代表流量大小,用igraph或networkD3的forceNetwork都能实现:

library(igraph)

graph <- graph_from_data_frame(links_2, directed = TRUE, vertices = nodes_2)
plot(graph, edge.width = E(graph)$value/5, vertex.size = 20, vertex.label.cex = 1.2)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 13:16:58