创建桑基图

Beginner

This tutorial is from open-source community. Access the source code

简介

在本教程中,我们将学习如何使用 Python 的 Matplotlib 库创建桑基图。桑基图是一种流程图,通常用于可视化能量或物质在系统中的流动。它们对于分析具有多个输入和输出的复杂系统特别有用。

虚拟机使用提示

虚拟机启动完成后,点击左上角切换到“笔记本”标签以访问 Jupyter Notebook 进行练习。

有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。

如果你在学习过程中遇到问题,随时向 Labby 提问。课程结束后提供反馈,我们将立即为你解决问题。

导入所需库

我们将首先导入使用 Matplotlib 创建桑基图所需的库。我们将从 matplotlib.sankey 模块中导入 Sankey 类,并从 Matplotlib 中导入 pyplot 模块。

import matplotlib.pyplot as plt
from matplotlib.sankey import Sankey

定义数据

接下来,我们将定义想要使用桑基图可视化的数据。在这个例子中,我们将使用 Moran 和 Shapiro 所著的《工程热力学基础》中例 8.6 的数据。这些数据表示通过朗肯动力循环的能量流。我们将把能量流定义为一个值列表。

Hdot = [260.431, 35.078, 180.794, 221.115, 22.700,
        142.361, 10.193, 10.210, 43.670, 44.312,
        68.631, 10.758, 10.758, 0.017, 0.642,
        232.121, 44.559, 100.613, 132.168]  ## MW

创建图形和坐标轴

我们将创建一个图形对象,并向其中添加一组坐标轴。我们还将设置绘图的标题。

fig = plt.figure(figsize=(8, 9))
ax = fig.add_subplot(1, 1, 1, xticks=[], yticks=[],
                     title="Rankine Power Cycle: Example 8.6 from Moran and "
                     "Shapiro\n\x22Fundamentals of Engineering Thermodynamics "
                     "\x22, 6th ed., 2008")

创建桑基图

我们将创建一个 Sankey 类的实例,并传入我们在步骤 3 中创建的坐标轴对象。我们还将设置流量值的格式和测量单位。然后,我们将使用 add 方法将流量添加到图表中。我们将使用 facecolor 参数指定每个流量的颜色,并使用 labels 参数指定每个流量的标签。我们还将使用 pathlengths 参数指定每个流量的路径长度,并使用 orientations 参数指定每个流量的方向。最后,我们将使用 connect 参数连接各个流量。

sankey = Sankey(ax=ax, format='%.3G', unit=' MW', gap=0.5, scale=1.0/Hdot[0])
sankey.add(patchlabel='\n\nPump 1', rotation=90, facecolor='#37c959',
           flows=[Hdot[13], Hdot[6], -Hdot[7]],
           labels=['Shaft power', '', None],
           pathlengths=[0.4, 0.883, 0.25],
           orientations=[1, -1, 0])
sankey.add(patchlabel='\n\nOpen\nheater', facecolor='#37c959',
           flows=[Hdot[11], Hdot[7], Hdot[4], -Hdot[8]],
           labels=[None, '', None, None],
           pathlengths=[0.25, 0.25, 1.93, 0.25],
           orientations=[1, 0, -1, 0], prior=0, connect=(2, 1))
sankey.add(patchlabel='\n\nPump 2', facecolor='#37c959',
           flows=[Hdot[14], Hdot[8], -Hdot[9]],
           labels=['Shaft power', '', None],
           pathlengths=[0.4, 0.25, 0.25],
           orientations=[1, 0, 0], prior=1, connect=(3, 1))
sankey.add(patchlabel='Closed\nheater', trunklength=2.914, fc='#37c959',
           flows=[Hdot[9], Hdot[1], -Hdot[11], -Hdot[10]],
           pathlengths=[0.25, 1.543, 0.25, 0.25],
           labels=['', '', None, None],
           orientations=[0, -1, 1, -1], prior=2, connect=(2, 0))
sankey.add(patchlabel='Trap', facecolor='#37c959', trunklength=5.102,
           flows=[Hdot[11], -Hdot[12]],
           labels=['\n', None],
           pathlengths=[1.0, 1.01],
           orientations=[1, 1], prior=3, connect=(2, 0))
sankey.add(patchlabel='Steam\ngenerator', facecolor='#ff5555',
           flows=[Hdot[15], Hdot[10], Hdot[2], -Hdot[3], -Hdot[0]],
           labels=['Heat rate', '', '', None, None],
           pathlengths=0.25,
           orientations=[1, 0, -1, -1, -1], prior=3, connect=(3, 1))
sankey.add(patchlabel='\n\n\nTurbine 1', facecolor='#37c959',
           flows=[Hdot[0], -Hdot[16], -Hdot[1], -Hdot[2]],
           labels=['', None, None, None],
           pathlengths=[0.25, 0.153, 1.543, 0.25],
           orientations=[0, 1, -1, -1], prior=5, connect=(4, 0))
sankey.add(patchlabel='\n\n\nReheat', facecolor='#37c959',
           flows=[Hdot[2], -Hdot[2]],
           labels=[None, None],
           pathlengths=[0.725, 0.25],
           orientations=[-1, 0], prior=6, connect=(3, 0))
sankey.add(patchlabel='Turbine 2', trunklength=3.212, facecolor='#37c959',
           flows=[Hdot[3], Hdot[16], -Hdot[5], -Hdot[4], -Hdot[17]],
           labels=[None, 'Shaft power', None, '', 'Shaft power'],
           pathlengths=[0.751, 0.15, 0.25, 1.93, 0.25],
           orientations=[0, -1, 0, -1, 1], prior=6, connect=(1, 1))
sankey.add(patchlabel='Condenser', facecolor='#58b1fa', trunklength=1.764,
           flows=[Hdot[5], -Hdot[18], -Hdot[6]],
           labels=['', 'Heat rate', None],
           pathlengths=[0.45, 0.25, 0.883],
           orientations=[-1, 1, 0], prior=8, connect=(2, 0))

添加标签和格式设置

我们将使用桑基图中每个补丁(patch)的 text 属性为其添加标签。我们还将把文本格式设置为加粗并增大字体大小。

diagrams = sankey.finish()
for diagram in diagrams:
    diagram.text.set_fontweight('bold')
    diagram.text.set_fontsize('10')
    for text in diagram.texts:
        text.set_fontsize('10')

显示绘图

最后,我们将使用 pyplot 模块的 show 方法来显示桑基图。

plt.show()

总结

在本教程中,我们学习了如何使用 Python 的 Matplotlib 库创建桑基图。我们使用了 matplotlib.sankey 模块中的 Sankey 类来创建图表,并使用每个补丁(patch)的 text 属性为图表添加标签和格式设置。桑基图是一种用于可视化能量或物质在复杂系统中流动的有用工具。