跳至主要内容

如何在 Excel、Python 和 R 中创建 Sankey 图

从基础概念到高级实现,学习用常用工具构建高效的 Sankey 图。了解关键组成、最佳实践与设计原则,让流向可视化更有说服力、更具洞察力。
· 9分钟 阅读

使用 AI 探索

Sankey 图的妙处在于它能将多阶段系统简化。无需在数据行中翻找最大能源损耗或预算分配,找出最粗的流向即可一眼识别。这使其适用于能源管理、财务分析、营销漏斗优化,以及任何理解资源流动与转化比精确数值对比更重要的场景。

如果您希望在流向可视化之外拓展分析能力,我们的 Power BI 数据可视化课程 和 Tableau 数据可视化课程 将教您使用行业领先的商业智能平台创建专业仪表板与交互式报告。

什么是 Sankey 图?

Sankey 图是一种特殊的流向可视化,其连接箭头的宽度代表在不同阶段、类别或实体之间的流量大小。与展示流程步骤的流程图或比较离散数值的柱状图不同,Sankey 图擅长展示数量如何在系统中流动、转化或被分配。

Sankey 图组件示意。图片来源:作者。

上图展示了年预算 100,000 美元如何在不同类别中流动。请注意,营销分配(40,000 美元)的流向明显比研发(25,000 美元)更粗,使比例差异一目了然。

Sankey 图的历史与演进

已知的第一张 Sankey 图诞生于 1898 年,当时 Matthew Henry Phineas Riall Sankey 上尉用它展示蒸汽机的能效。他的图显示,只有一小部分燃料能量用于有效功,大部分以废热形式损失。

the very first Sankey diagram

不过,按比例展示流量的概念早于 Sankey 上尉。Charles Joseph Minard 在 1869 年创作了许多人认为最著名的流向图,描绘了拿破仑 1812 年俄国战役的惨败。Minard 的图用线条粗细表示幸存士兵数量,展示了军队在进入俄国并撤退过程中的规模递减。

Sankey 图的组成部分

理解 Sankey 图的关键元素有助于您更好地解读已有图表,并高效创建自己的图表。

  • 节点 代表系统中的类别、阶段或实体。在我们的预算示例中,“Annual Budget”“Marketing”“Digital Ads”都是节点。 源节点(如“Annual Budget”)通常在左侧,而目标节点(如“Digital Ads”)在右侧,但也可根据布局偏好调整。
  • 流或链接 是节点之间的有向连接,其宽度与所代表的数值成正比。从 Annual Budget 到 Marketing 的粗橙色流代表 40,000 美元,而到 Content 的细流仅代表 5,000 美元。按比例的宽度是 Sankey 图凸显数量差异的核心特征。
  • 数值 是决定每条流宽度的数值型数据。它们可以表示金钱、能源、材料、人员,或系统中任何可量化资源的流动。图表会根据这些数值自动计算合适的宽度,确保视觉准确性。
  • 流失 是表示损失、浪费或未到达目标节点就从系统中流出的资源的特殊流。尽管我们的预算示例未展示流失,但在展示热损失的能源图或展示客户流失的营销漏斗中,您会看到它们。

如何创建 Sankey 图

创建 Sankey 图的方式会因您偏好的工具与技术熟悉度而异。我们将用同一预算分配示例分别在 Excel、Python 和 R 中演示,便于您选择最契合工作流与专长的方法。

在 Excel 中创建 Sankey 图

Excel 没有原生的 Sankey 图类型,这意味着您需要使用第三方加载项来创建这种可视化。以我的经验,ChartExpo 是最流行且友好的选择之一。

ChartExpo 界面与 Sankey 图预览。图片来源:作者。

在创建图表之前,您需要将数据整理为“源-目标-数值”的结构,每一行表示一个流向连接。对我们的预算示例而言,即将每条预算分配作为一行,包含源类别、目标类别和金额。

安装 ChartExpo 后流程相当简单。首先从 Microsoft AppSource 或 Excel 加载项市场安装该加载项。然后,选择包含表头的数据区域,并在 ChartExpo 的可视化选项中选择 Sankey Chart。

加载项会根据您的数据结构自动识别源、目标和数值列。如上方界面所示,ChartExpo 提供图表预览,并可选择 Create Chart From Selection、自定义可视化,或将成品图表导出用于演示或报告。

在 Python 中创建 Sankey 图

Python 提供了出色的 Sankey 图创建选项,其中 Plotly 因其交互能力和专业输出质量而最为推荐。我们将使用开篇的预算分配示例,通过代码复现相同的可视化。

步骤 1:数据准备

先将数据整理为 Plotly 期望的格式。您需要三个主要组成部分:节点名称列表,以及分别指定每条流的源索引、目标索引与数值的数组。

import plotly.graph_objects as go

# Define all nodes in your diagram
nodes = ["Annual Budget", "Marketing", "Operations", "R&D", 
         "Digital Ads", "Events", "Content", "Salaries", 
         "Office", "Utilities", "Software", "Equipment"]

# Define the connections (using node indices)
source_indices = [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3]
target_indices = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
values = [40, 35, 25, 25, 10, 5, 20, 10, 5, 15, 10]

索引对应于节点列表中的位置,因此 source_indices = [0, 0, 0] 表示前三条流都起始于 "Annual Budget"(位置 0)。

步骤 2:基础 Sankey 构建

使用 Plotly 的 Sankey 对象创建核心图表结构。关键参数是节点定义与链接规格。

fig = go.Figure(data=[go.Sankey(
    node=dict(
        label=nodes,
        pad=15,
        thickness=20
    ),
    link=dict(
        source=source_indices,
        target=target_indices,
        value=values
    )
)])

这将创建一个具有默认样式的可用 Sankey 图。pad 控制节点间距,thickness 决定节点矩形的宽度。

步骤 3:样式与自定义

通过配色、布局优化与专业格式增强图表。

# Add colors and transparency
fig.update_traces(
    node_color=["#1f77b4", "#ff7f0e", "#2ca02c", "#d62728",
                "#ff9999", "#ff9999", "#ff9999", "#90ee90",
                "#90ee90", "#90ee90", "#ffcccb", "#ffcccb"],
    link_color=["rgba(255, 127, 14, 0.4)", "rgba(44, 160, 44, 0.4)",
                "rgba(214, 39, 40, 0.4)", "rgba(255, 127, 14, 0.6)",
                "rgba(255, 127, 14, 0.6)", "rgba(255, 127, 14, 0.6)",
                "rgba(44, 160, 44, 0.6)", "rgba(44, 160, 44, 0.6)",
                "rgba(44, 160, 44, 0.6)", "rgba(214, 39, 40, 0.6)",
                "rgba(214, 39, 40, 0.6)"]
)

# Update layout for better presentation
fig.update_layout(
    title="Annual Budget Allocation",
    font=dict(size=16, family="Arial Black", color="black"),
    width=900,
    height=600
)

步骤 4:展示与导出

展示图表,并按不同用途保存为多种格式。

fig.show()  # Display in Jupyter notebook or browser

# Export options
fig.write_html("budget_sankey.html")  # Interactive web version
fig.write_image("budget_sankey.png")  # Static image

对于 Web 应用,您可以将其直接集成到 Dash 应用中,让 Sankey 图成为交互式仪表板的一部分。最终的可视化效果与开篇图完全一致。我们还有一段优秀的跟练视频,教您如何使用 Plotly 和 Dash 构建仪表板,您可以亲自尝试这个思路。

在 R 中创建 Sankey 图

R 可通过 networkD3 包创建 Sankey 图,实现交互式、可用于网页的可视化。我们将用熟悉的预算分配数据展示 R 如何以内建交互功能实现同等专业效果。

networkD3 包专为在 R 中创建基于 D3.js 的网络可视化(包括 Sankey 图)而设计。其优势包括:自动交互(悬停、缩放)、轻松集成 R Markdown 报告,以及便捷的网页部署导出选项。

步骤 1:环境与数据准备

先安装并加载所需包,然后按 networkD3 期望的格式整理数据。

# Install required packages (run once)
install.packages(c("networkD3", "dplyr"))

# Load libraries
library(networkD3)
library(dplyr)

# Create nodes dataframe
nodes <- data.frame(
  name = c("Annual Budget", "Marketing", "Operations", "R&D",
           "Digital Ads", "Events", "Content", "Salaries", 
           "Office", "Utilities", "Software", "Equipment")
)

# Create links dataframe (note: networkD3 uses 0-based indexing)
links <- data.frame(
  source = c(0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3),
  target = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11),
  value = c(40, 35, 25, 25, 10, 5, 20, 10, 5, 15, 10)
)

与 Python 的主要不同在于,R 需要分别为节点与链接创建数据框,且链接数据框使用从零开始的索引来引用节点位置。

步骤 2:基础 Sankey 构建

使用 sankeyNetwork() 函数并提供必要参数创建图表。

# Create basic Sankey diagram
sankey_plot <- sankeyNetwork(
  Links = links,
  Nodes = nodes,
  Source = "source",
  Target = "target", 
  Value = "value",
  NodeID = "name",
  units = "K USD"
)

# Display the plot
Sankey_plot

这会生成一个交互式 Sankey 图,用户可悬停查看精确数值,并拖动节点重组布局。

步骤 3:自定义与样式

通过配色、尺寸和专业格式选项增强图表。

# Advanced Sankey with customization
(sankey_advanced <- sankeyNetwork(
  Links = links,
  Nodes = nodes,
  Source = "source",
  Target = "target",
  Value = "value",
  NodeID = "name",
  units = "K USD",
  fontSize = 14,
  fontFamily = "Arial",
  nodeWidth = 30,
  nodePadding = 20,
  margin = list(top = 50, right = 50, bottom = 50, left = 50),
  height = 600,
  width = 900
))

步骤 4:导出与集成选项

R 便于将交互式图表保存为多种格式,并集成到报告中。

# Save as HTML file
library(htmlwidgets)
saveWidget(sankey_advanced, "budget_sankey.html", selfcontained = TRUE)

# For R Markdown integration, simply include the plot object
# The diagram will render as an interactive widget in your document

# For static image export (optional - requires webshot2 package)
install.packages("webshot2")
library(webshot2)

webshot("budget_sankey.html", "budget_sankey.png", vwidth = 900, vheight = 600)

使用 R 的 networkD3 包创建的交互式 Sankey 图。图片来源:作者。

该图与我们在 Python 和 Excel 中的版本提供相同的视觉洞察,同时内置的交互功能有助于用户更深入地探索数据。

Sankey 图的替代方案与比较

当类别之间存在清晰的方向关系,且流量大小比精确比较更重要时,Sankey 图效果最佳。不过,在若干情况下,其他可视化方式更为合适。

不应使用 Sankey 图的场景

当类别之间不存在方向性流动时,请避免使用 Sankey 图。如果您的数据仅展示不同群体或分类而无其间的迁移,柱状图或饼图能更清晰地传达信息。例如,不涉及流动的不同公司市场份额对比,用柱状图更合适。

当您需要精确的数值比较时,请略过它们。虽然 Sankey 图能有效显示相对大小,但宽度变化使读者难以获取精确数值或进行细致对比。若相关方需要准确比较具体百分比或金额,表格或柱状图更胜任。

当数据过于复杂导致图表凌乱时,请考虑替代方案。超过 10–15 个节点或高度互联的流向会让 Sankey 图在视觉上过于拥挤。交叉与重叠的流线会让人难以追踪系统中的单一路径。

当受众对 Sankey 图不熟悉时,请选择更简单的可视化。由于其不如柱状图或折线图常见,一些受众可能会把精力放在理解图表形式上,而非解读数据。在面向大众的演示中,除非流向关系对您的信息至关重要,否则请使用熟悉的图表类型。

特定场景下更优的替代方案

Sankey-Alluvial(堆流图、河流图) 更适用于按类别或时间维度追踪多期或多阶段变化的流向。Sankey 图显示某一时点系统内的数量流动,而堆流图擅长展示类别数据的演变。例如,追踪选民在多次选举中如何在政党之间流动,或学生在大学期间如何更换专业,更适合用堆流图而非 Sankey 图。

平行坐标图 更适合比较多变量数据,在同一时间查看多个维度的模式。当每个数据点包含许多变量并希望识别簇或离群点时,它们表现出色。例如,在价格、燃油效率、安全评级和性能指标上比较汽车,用平行坐标图比勉强套入流向格式更合适。

凸位图(Bump Chart) 比 Sankey 或堆流图更有效地处理随时间的排名变化。当需要展示不同实体在多个时期中名次的升降时,凸位图能清晰呈现轨迹,而无需承受流线的视觉复杂度。比如追踪不同公司的市场地位在各季度的变化,或球队在赛季中的联赛排名变动。

想进一步了解,请阅读我们的博客文章 DataCamp 上值得学习的 5 门商业智能课程,帮助您掌握重要的 BI 工具。

结论

成功的可视化取决于为具体情境选择合适的工具。当方向性流动关系比精确数值对比更重要,且受众需要快速识别系统中最关键的流向时,请使用 Sankey 图。

若您希望将视野拓展到 Sankey 图之外,我们的博客文章 适合各层级的 10 个数据可视化项目创意 提供涵盖不同复杂度的实践建议,助您打造可视化作品集。这些项目有助于培养批判性思维,并为您的可视化能力提供可量化的成果证明。

Vinod Chugani

作者

Vinod Chugani

Vinod Chugani 的职业生涯始于东京,曾任摩根大通最年轻的对冲基金销售台负责人,随后在雷曼兄弟创下个人销售纪录,之后又打造了覆盖 30 个国家的电子分销业务,营收突破 1 亿新元,随后转向数据领域。他毕业于杜克大学经济学专业,亦为 NYC Data Science Academy 校友,并在 100 多名申请者中成为Hugo Bowne-Anderson 在 Maven 开设的 “Building AI Applications” 课程的三位奖学金获得者之一。目前,他为 DataCamp、KDnuggets、Machine Learning Mastery 和 Statology 撰稿,内容涵盖从统计学到代理式 AI 等主题,并在 NYC Data Science Academy 指导数据从业者,已完成超过 1,000 场一对一辅导。

 

FAQs

Sankey 图与流程图有何不同?

流程图展示流程步骤和决策点,而 Sankey 图专门可视化不同阶段之间资源、能源或数据的流动及其数量。Sankey 图中箭头的宽度与被测量的数值成正比;相对地,流程图侧重于流程逻辑而非数量。

哪类数据最适合用于 Sankey 图?

Sankey 图最适合展示从一个阶段到另一个阶段的移动或转化的流向型数据,例如能源分配、网站转化漏斗、供应链流向或预算分配。它不适用于纯类别数据或变量之间没有方向性关系的数据集。

有哪些无需编码即可在线创建 Sankey 图的优秀工具?

对于偏好基于网页的方案的用户,SankeyMATIC 提供免费、简洁的基础图界面,而 Flourish 适合专业演示,具备更高级功能与交互性。Google Charts 和 Highcharts 非常适合开发者将 Sankey 图嵌入网站;Visual Paradigm 则作为更广泛商业工具套件的一部分,提供全面的制图能力。

何时应避免使用 Sankey 图?

当您需要精确的数值比较(因为流宽难以精确度量)、当数据类别过多导致视觉混乱,或当数据点之间并无真实的方向性流动时,请避免使用 Sankey 图。如果受众不熟悉这种可视化类型,也可考虑更简单的替代方案,以免新奇性盖过信息本身。

在 Sankey 图中如何处理负值或损失?

Sankey 图通常不直接显示负值,因为箭头宽度代表正向数量。相应地,可将损失显示为从节点流出的独立流,或使用不连接到目标节点的“流失”来表示浪费或丢失的资源。

Sankey 图与堆流图(Alluvial)有何区别?

Sankey 图关注某一时点的流量数量;而堆流图展示类别数据在多个时间段或阶段中的变化。堆流图更适合追踪迁移、类别变化或随时间的演变。

主题