文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

怎么使用Python绘制惊艳的桑基图

2023-07-06 01:51

关注

本篇内容介绍了“怎么使用Python绘制惊艳的桑基图”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

桑基图简介

很多时候,我们需要一种必须可视化数据如何在实体之间流动的情况。例如,以居民如何从一个国家迁移到另一个国家为例。这里演示了有多少居民从英格兰迁移到北爱尔兰、苏格兰和威尔士。

怎么使用Python绘制惊艳的桑基图

从这个 桑基图 (Sankey)可视化中可以明显看出,从England迁移到Wales的居民多于从Scotland或Northern Ireland迁移的居民。

什么是桑基图?

桑基图通常描绘 从一个实体(或节点)到另一个实体(或节点)的数据流。

数据流向的实体被称为节点,数据流起源的节点是源节点(例如左侧的England),流结束的节点是 目标节点(例如右侧的Wales)。源节点和目标节点通常表示为带有标签的矩形。

流动本身由直线或曲线路径表示,称为链接。流/链接的宽度与流的量/数量成正比。在上面的例子中,从英格兰到威尔士的流动(即居民迁移)比从英格兰到苏格兰或北爱尔兰的流动(即居民迁移)更广泛(更多),表明迁移到威尔士的居民数量多于其他国家。

桑基图可用于表示能量、金钱、成本的流动,以及任何具有流动概念的事物。

米纳尔关于拿破仑入侵俄罗斯的经典图表可能是桑基图表最著名的例子。这种使用桑基图的可视化非常有效地显示了法国军队在前往俄罗斯和返回的途中是如何进步(或减少?)的。

怎么使用Python绘制惊艳的桑基图

本文中,我们使用 python 的 plotly 绘制桑基图。

如何绘制桑基图?

本文使用 2021 年奥运会数据集绘制桑基图。该数据集包含有关奖牌总数的详细信息——国家、奖牌总数以及金牌、银牌和铜牌的单项总数。我们通过绘制一个桑基图来了解一个国家赢得的金牌、银牌和铜牌数。

df_medals = pd.read_excel("data/Medals.xlsx")print(df_medals.info())df_medals.rename(columns={'Team/NOC':'Country', 'Total': 'Total Medals', 'Gold':'Gold Medals', 'Silver': 'Silver Medals', 'Bronze': 'Bronze Medals'}, inplace=True)df_medals.drop(columns=['Unnamed: 7','Unnamed: 8','Rank by Total'], inplace=True)df_medals
RangeIndex: 93 entries, 0 to 92Data columns (total 9 columns): # Column Non-Null CountDtype--------- ------------------- 0 Rank 93 non-null int64 1 Team/NOC 93 non-null object  2 Gold 93 non-null int64 3 Silver 93 non-null int64 4 Bronze 93 non-null int64 5 Total93 non-null int64 6 Rank by Total93 non-null int64 7 Unnamed: 7 0 non-nullfloat64 8 Unnamed: 8 1 non-nullfloat64dtypes: float64(2), int64(6), object(1)memory usage: 6.7+ KBNone

怎么使用Python绘制惊艳的桑基图

桑基图绘图基础

使用 plotly 的 go.Sankey,该方法带有2 个参数 ——nodes 和 links (节点和链接)。

注意:所有节点——源和目标都应该有唯一的标识符。

在本文奥林匹克奖牌数据集情况中:

Source是国家。将前 3 个国家(美国、中国和日本)视为源节点。用以下(唯一的)标识符、标签和颜色来标记这些源节点:

Target是金牌、银牌或铜牌。用以下(唯一的)标识符、标签和颜色来标记这些目标节点:

Link(源节点和目标节点之间)是每种类型奖牌的数量。在每个源中有3个链接,每个链接都以目标结尾——金牌、银牌和铜牌。所以总共有9个链接。每个环节的宽度应为金牌、银牌和铜牌的数量。用以下源标记这些链接到目标、值和颜色:

需要实例化 2 个 python dict 对象来表示

并将其传递给plotly的 go.Sankey。

列表的每个索引(标签、源、目标、值和颜色)分别对应一个节点或链接。

NODES = dict( # 0 1 23 4 5 label = ["United States of America", "People's Republic of China", "Japan", "Gold", "Silver", "Bronze"],color = ["seagreen", "dodgerblue", "orange", "gold", "silver", "brown" ],)LINKS = dict( source = [0,0,0,1,1,1,2,2,2], # 链接的起点或源节点target = [3,4,5,3,4,5,3,4,5], # 链接的目的地或目标节点value =[ 39, 41, 33, 38, 32, 18, 27, 14, 17], # 链接的宽度(数量)# 链接的颜色# 目标节点: 3-Gold4-Silver5-Bronzecolor = [ "lightgreen", "lightgreen", "lightgreen",# 源节点:0 - 美国 States of America"lightskyblue", "lightskyblue", "lightskyblue",# 源节点:1 - 中华人民共和国China"bisque", "bisque", "bisque"],)# 源节点:2 - 日本data = go.Sankey(node = NODES, link = LINKS)fig = go.Figure(data)fig.show()

怎么使用Python绘制惊艳的桑基图

这是一个非常基本的桑基图。但是否注意到图表太宽并且银牌出现在金牌之前?

接下来介绍如何调整节点的位置和宽度。

调整节点位置和图表宽度

为节点添加 x 和 y 位置以明确指定节点的位置。值应介于 0 和 1 之间。

NODES = dict( # 0 1 23 4 5 label = ["United States of America", "People's Republic of China", "Japan", "Gold", "Silver", "Bronze"],color = ["seagreen", "dodgerblue", "orange", "gold", "silver", "brown" ],)x = [ 0,0,0,0.5,0.5,0.5],y = [ 0,0.5,1,0.1,0.5,1],)data = go.Sankey(node = NODES, link = LINKS)fig = go.Figure(data)fig.update_layout(title="Olympics - 2021: Country &Medals",font_size=16)fig.show()

于是得到了一个紧凑的桑基图:

怎么使用Python绘制惊艳的桑基图

下面看看代码中传递的各种参数如何映射到图中的节点和链接。

怎么使用Python绘制惊艳的桑基图

代码如何映射到桑基图

添加有意义的悬停标签

我们都知道plotly绘图是交互的,我们可以将鼠标悬停在节点和链接上以获取更多信息。

怎么使用Python绘制惊艳的桑基图

带有默认悬停标签的桑基图

当将鼠标悬停在图上,将会显示详细信息。悬停标签中显示的信息是默认文本:节点、节点名称、传入流数、传出流数和总值。

例如:

如果我们觉得这些标签太冗长了,我们可以对此进程改进。使用hovertemplate参数改进悬停标签的格式

NODES = dict( # 0 1 23 4 5label = ["United States of America", "People's Republic of China", "Japan", "Gold", "Silver", "Bronze"],color = ["seagreen", "dodgerblue","orange", "gold", "silver", "brown" ],x = [ 0,0, 0,0.5,0.5,0.5],y = [ 0,0.5, 1,0.1,0.5,1],hovertemplate=" ",)LINK_LABELS = []for country in ["USA","China","Japan"]:for medal in ["Gold","Silver","Bronze"]:LINK_LABELS.append(f"{country}-{medal}")LINKS = dict(source = [0,0,0,1,1,1,2,2,2],  # 链接的起点或源节点 target = [3,4,5,3,4,5,3,4,5],  # 链接的目的地或目标节点 value =[ 39, 41, 33, 38, 32, 18, 27, 14, 17],  # 链接的宽度(数量)  # 链接的颜色 # 目标节点:3-Gold4 -Silver5-Bronze color = ["lightgreen", "lightgreen", "lightgreen", # 源节点:0 - 美国"lightskyblue", "lightskyblue", "lightskyblue", # 源节点:1 - 中国"bisque", "bisque", "bisque"],# 源节点:2 - 日本 label = LINK_LABELS,  hovertemplate="%{label}",)data = go.Sankey(node = NODES, link = LINKS)fig = go.Figure(data)fig.update_layout(title="Olympics - 2021: Country &Medals",font_size=16, width=1200, height=500,)fig.update_traces(valueformat='3d', valuesuffix='Medals', selector=dict(type='sankey'))fig.update_layout(hoverlabel=dict(bgcolor="lightgray",font_size=16,font_family="Rockwell"))fig.show("png") #fig.show()

怎么使用Python绘制惊艳的桑基图

带有改进的悬停标签的桑基图

对多个节点和级别进行泛化相对于链接,节点被称为源和目标。作为一个链接目标的节点可以是另一个链接的源。

该代码可以推广到处理数据集中的所有国家。

还可以将图表扩展到另一个层次,以可视化各国的奖牌总数。

NUM_COUNTRIES = 5X_POS, Y_POS = 0.5, 1/(NUM_COUNTRIES-1)NODE_COLORS = ["seagreen", "dodgerblue", "orange", "palevioletred", "darkcyan"]LINK_COLORS = ["lightgreen", "lightskyblue", "bisque", "pink", "lightcyan"]source = []node_x_pos, node_y_pos = [], []node_labels, node_colors = [], NODE_COLORS[0:NUM_COUNTRIES]link_labels, link_colors, link_values = [], [], [] # 第一组链接和节点for i in range(NUM_COUNTRIES):source.extend([i]*3)node_x_pos.append(0.01)node_y_pos.append(round(i*Y_POS+0.01,2))country = df_medals['Country'][i]node_labels.append(country) for medal in ["Gold", "Silver", "Bronze"]:link_labels.append(f"{country}-{medal}")link_values.append(df_medals[f"{medal} Medals"][i])link_colors.extend([LINK_COLORS[i]]*3)source_last = max(source)+1target = [ source_last, source_last+1, source_last+2] * NUM_COUNTRIEStarget_last = max(target)+1node_labels.extend(["Gold", "Silver", "Bronze"])node_colors.extend(["gold", "silver", "brown"])node_x_pos.extend([X_POS, X_POS, X_POS])node_y_pos.extend([0.01, 0.5, 1])# 最后一组链接和节点source.extend([ source_last, source_last+1, source_last+2])target.extend([target_last]*3)node_labels.extend(["Total Medals"])node_colors.extend(["grey"])node_x_pos.extend([X_POS+0.25])node_y_pos.extend([0.5])for medal in ["Gold","Silver","Bronze"]:link_labels.append(f"{medal}")link_values.append(df_medals[f"{medal} Medals"][:i+1].sum())link_colors.extend(["gold", "silver", "brown"])print("node_labels", node_labels)print("node_x_pos", node_x_pos); print("node_y_pos", node_y_pos)
node_labels ['United States of America', "People's Republic of China",  'Japan', 'Great Britain', 'ROC', 'Gold', 'Silver',  'Bronze', 'Total Medals']node_x_pos [0.01, 0.01, 0.01, 0.01, 0.01, 0.5, 0.5, 0.5, 0.75]node_y_pos [0.01, 0.26, 0.51, 0.76, 1.01, 0.01, 0.5, 1, 0.5]
# 显示的图NODES = dict(pad= 20, thickness = 20,  line = dict(color = "lightslategrey", width = 0.5), hovertemplate=" ", label = node_labels,  color = node_colors, x = node_x_pos,  y = node_y_pos, )LINKS = dict(source = source,  target = target,  value = link_values,  label = link_labels,  color = link_colors, hovertemplate="%{label}",)data = go.Sankey(arrangement='snap',  node = NODES,  link = LINKS)fig = go.Figure(data)fig.update_traces(valueformat='3d', valuesuffix=' Medals', selector=dict(type='sankey'))fig.update_layout(title="Olympics - 2021: Country &Medals",font_size=16,width=1200,height=500,)fig.update_layout(hoverlabel=dict(bgcolor="grey", font_size=14, font_family="Rockwell"))fig.show("png")

怎么使用Python绘制惊艳的桑基图

“怎么使用Python绘制惊艳的桑基图”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯