<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
很多時候,我們需要一種必須視覺化資料如何在實體之間流動的情況。例如,以居民如何從一個國家遷移到另一個國家為例。這裡演示了有多少居民從英格蘭遷移到北愛爾蘭、蘇格蘭和威爾士。
從這個 桑基圖 (Sankey)視覺化中可以明顯看出,從England遷移到Wales的居民多於從Scotland或Northern Ireland遷移的居民。
桑基圖通常描繪 從一個實體(或節點)到另一個實體(或節點)的資料流。
資料流向的實體被稱為節點,資料流起源的節點是源節點(例如左側的England),流結束的節點是 目標節點(例如右側的Wales)。源節點和目標節點通常表示為帶有標籤的矩形。
流動本身由直線或曲線路徑表示,稱為連結。流/連結的寬度與流的量/數量成正比。在上面的例子中,從英格蘭到威爾士的流動(即居民遷移)比從英格蘭到蘇格蘭或北愛爾蘭的流動(即居民遷移)更廣泛(更多),表明遷移到威爾士的居民數量多於其他國家。
桑基圖可用於表示能量、金錢、成本的流動,以及任何具有流動概念的事物。
米納爾關於拿破崙入侵俄羅斯的經典圖表可能是桑基圖表最著名的例子。這種使用桑基圖的視覺化非常有效地顯示了法國軍隊在前往俄羅斯和返回的途中是如何進步(或減少?)的。
本文中,我們使用 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
<class 'pandas.core.frame.DataFrame'> RangeIndex: 93 entries, 0 to 92 Data columns (total 9 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 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 Total 93 non-null int64 6 Rank by Total 93 non-null int64 7 Unnamed: 7 0 non-null float64 8 Unnamed: 8 1 non-null float64 dtypes: float64(2), int64(6), object(1) memory usage: 6.7+ KB None
使用 plotly 的 go.Sankey,該方法帶有2 個引數 ——nodes 和 links (節點和連結)。
注意:所有節點——源和目標都應該有唯一的識別符號。
在本文奧林匹克獎牌資料集情況中:
Source是國家。將前 3 個國家(美國、中國和日本)視為源節點。用以下(唯一的)識別符號、標籤和顏色來標記這些源節點:
Target是金牌、銀牌或銅牌。用以下(唯一的)識別符號、標籤和顏色來標記這些目標節點:
Link(源節點和目標節點之間)是每種型別獎牌的數量。在每個源中有3個連結,每個連結都以目標結尾——金牌、銀牌和銅牌。所以總共有9個連結。每個環節的寬度應為金牌、銀牌和銅牌的數量。用以下源標記這些連結到目標、值和顏色:
需要範例化 2 個 python dict 物件來表示
並將其傳遞給plotly的 go.Sankey。
列表的每個索引(標籤、源、目標、值和顏色)分別對應一個節點或連結。
NODES = dict( # 0 1 2 3 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-Gold 4-Silver 5-Bronze color = [ "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()
這是一個非常基本的桑基圖。但是否注意到圖表太寬並且銀牌出現在金牌之前?
接下來介紹如何調整節點的位置和寬度。
為節點新增 x 和 y 位置以明確指定節點的位置。值應介於 0 和 1 之間。
NODES = dict( # 0 1 2 3 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()
於是得到了一個緊湊的桑基圖:
下面看看程式碼中傳遞的各種引數如何對映到圖中的節點和連結。
程式碼如何對映到桑基圖
我們都知道plotly繪圖是互動的,我們可以將滑鼠懸停在節點和連結上以獲取更多資訊。
帶有預設懸停標籤的桑基圖
當將滑鼠懸停在圖上,將會顯示詳細資訊。懸停標籤中顯示的資訊是預設文字:節點、節點名稱、傳入流數、傳出流數和總值。
例如:
如果我們覺得這些標籤太冗長了,我們可以對此程序改進。使用hovertemplate引數改進懸停標籤的格式
NODES = dict( # 0 1 2 3 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], 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-Gold 4 -Silver 5-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()
帶有改進的懸停標籤的桑基圖
對多個節點和級別進行泛化相對於連結,節點被稱為源和目標。作為一個連結目標的節點可以是另一個連結的源。
該程式碼可以推廣到處理資料集中的所有國家。
還可以將圖表擴充套件到另一個層次,以視覺化各國的獎牌總數。
NUM_COUNTRIES = 5 X_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)+1 target = [ source_last, source_last+1, source_last+2] * NUM_COUNTRIES target_last = max(target)+1 node_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繪製桑基圖的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45