溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么使用Python繪制驚艷的?;鶊D

發(fā)布時(shí)間:2023-04-13 10:03:22 來源:億速云 閱讀:98 作者:iii 欄目:編程語言

本篇內(nèi)容介紹了“怎么使用Python繪制驚艷的?;鶊D”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

?;鶊D簡(jiǎn)介

很多時(shí)候,我們需要一種必須可視化數(shù)據(jù)如何在實(shí)體之間流動(dòng)的情況。例如,以居民如何從一個(gè)國(guó)家遷移到另一個(gè)國(guó)家為例。這里演示了有多少居民從英格蘭遷移到北愛爾蘭、蘇格蘭和威爾士。

怎么使用Python繪制驚艷的?;鶊D

從這個(gè) 桑基圖 (Sankey)可視化中可以明顯看出,從England遷移到Wales的居民多于從Scotland或Northern Ireland遷移的居民。

什么是?;鶊D?

?;鶊D通常描繪 從一個(gè)實(shí)體(或節(jié)點(diǎn))到另一個(gè)實(shí)體(或節(jié)點(diǎn))的數(shù)據(jù)流。

數(shù)據(jù)流向的實(shí)體被稱為節(jié)點(diǎn),數(shù)據(jù)流起源的節(jié)點(diǎn)是源節(jié)點(diǎn)(例如左側(cè)的England),流結(jié)束的節(jié)點(diǎn)是 目標(biāo)節(jié)點(diǎn)(例如右側(cè)的Wales)。源節(jié)點(diǎn)和目標(biāo)節(jié)點(diǎn)通常表示為帶有標(biāo)簽的矩形。

流動(dòng)本身由直線或曲線路徑表示,稱為鏈接。流/鏈接的寬度與流的量/數(shù)量成正比。在上面的例子中,從英格蘭到威爾士的流動(dòng)(即居民遷移)比從英格蘭到蘇格蘭或北愛爾蘭的流動(dòng)(即居民遷移)更廣泛(更多),表明遷移到威爾士的居民數(shù)量多于其他國(guó)家。

?;鶊D可用于表示能量、金錢、成本的流動(dòng),以及任何具有流動(dòng)概念的事物。

米納爾關(guān)于拿破侖入侵俄羅斯的經(jīng)典圖表可能是桑基圖表最著名的例子。這種使用?;鶊D的可視化非常有效地顯示了法國(guó)軍隊(duì)在前往俄羅斯和返回的途中是如何進(jìn)步(或減少?)的。

怎么使用Python繪制驚艷的?;鶊D

本文中,我們使用 python 的 plotly 繪制?;鶊D。

如何繪制?;鶊D?

本文使用 2021 年奧運(yùn)會(huì)數(shù)據(jù)集繪制?;鶊D。該數(shù)據(jù)集包含有關(guān)獎(jiǎng)牌總數(shù)的詳細(xì)信息——國(guó)家、獎(jiǎng)牌總數(shù)以及金牌、銀牌和銅牌的單項(xiàng)總數(shù)。我們通過繪制一個(gè)?;鶊D來了解一個(gè)國(guó)家贏得的金牌、銀牌和銅牌數(shù)。

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 92
Data 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-nullfloat64
dtypes: float64(2), int64(6), object(1)
memory usage: 6.7+ KB
None

怎么使用Python繪制驚艷的桑基圖

?;鶊D繪圖基礎(chǔ)

使用 plotly 的 go.Sankey,該方法帶有2 個(gè)參數(shù) ——nodes 和 links (節(jié)點(diǎn)和鏈接)。

注意:所有節(jié)點(diǎn)——源和目標(biāo)都應(yīng)該有唯一的標(biāo)識(shí)符。

在本文奧林匹克獎(jiǎng)牌數(shù)據(jù)集情況中:

Source是國(guó)家。將前 3 個(gè)國(guó)家(美國(guó)、中國(guó)和日本)視為源節(jié)點(diǎn)。用以下(唯一的)標(biāo)識(shí)符、標(biāo)簽和顏色來標(biāo)記這些源節(jié)點(diǎn):

  • 0:美國(guó):綠色

  • 1:中國(guó):藍(lán)色

  • 2:日本:橙色

Target是金牌、銀牌或銅牌。用以下(唯一的)標(biāo)識(shí)符、標(biāo)簽和顏色來標(biāo)記這些目標(biāo)節(jié)點(diǎn):

  • 3:金牌:金色

  • 4:銀牌:銀色

  • 5:銅牌:棕色

Link(源節(jié)點(diǎn)和目標(biāo)節(jié)點(diǎn)之間)是每種類型獎(jiǎng)牌的數(shù)量。在每個(gè)源中有3個(gè)鏈接,每個(gè)鏈接都以目標(biāo)結(jié)尾——金牌、銀牌和銅牌。所以總共有9個(gè)鏈接。每個(gè)環(huán)節(jié)的寬度應(yīng)為金牌、銀牌和銅牌的數(shù)量。用以下源標(biāo)記這些鏈接到目標(biāo)、值和顏色:

  • 0 (美國(guó)) 至 3,4,5 : 39, 41, 33

  • 1 (中國(guó)) 至 3,4,5 : 38, 32, 18

  • 2 (日本) 至 3,4,5 : 27, 14, 17

需要實(shí)例化 2 個(gè) python dict 對(duì)象來表示

  • nodes (源和目標(biāo)):標(biāo)簽和顏色作為單獨(dú)的列表和

  • links:源節(jié)點(diǎn)、目標(biāo)節(jié)點(diǎn)、值(寬度)和鏈接的顏色作為單獨(dú)的列表

并將其傳遞給plotly的 go.Sankey。

列表的每個(gè)索引(標(biāo)簽、源、目標(biāo)、值和顏色)分別對(duì)應(yīng)一個(gè)節(jié)點(diǎn)或鏈接。

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], # 鏈接的起點(diǎn)或源節(jié)點(diǎn)
target = [3,4,5,3,4,5,3,4,5], # 鏈接的目的地或目標(biāo)節(jié)點(diǎn)
value =[ 39, 41, 33, 38, 32, 18, 27, 14, 17], # 鏈接的寬度(數(shù)量)
# 鏈接的顏色
# 目標(biāo)節(jié)點(diǎn): 3-Gold4-Silver5-Bronze
color = [ 
"lightgreen", "lightgreen", "lightgreen",# 源節(jié)點(diǎn):0 - 美國(guó) States of America
"lightskyblue", "lightskyblue", "lightskyblue",# 源節(jié)點(diǎn):1 - 中華人民共和國(guó)China
"bisque", "bisque", "bisque"],)# 源節(jié)點(diǎn):2 - 日本
data = go.Sankey(node = NODES, link = LINKS)
fig = go.Figure(data)
fig.show()

怎么使用Python繪制驚艷的?;鶊D

這是一個(gè)非?;镜纳;鶊D。但是否注意到圖表太寬并且銀牌出現(xiàn)在金牌之前?

接下來介紹如何調(diào)整節(jié)點(diǎn)的位置和寬度。

調(diào)整節(jié)點(diǎn)位置和圖表寬度

為節(jié)點(diǎn)添加 x 和 y 位置以明確指定節(jié)點(diǎn)的位置。值應(yīng)介于 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()

于是得到了一個(gè)緊湊的?;鶊D:

怎么使用Python繪制驚艷的?;鶊D

下面看看代碼中傳遞的各種參數(shù)如何映射到圖中的節(jié)點(diǎn)和鏈接。

怎么使用Python繪制驚艷的?;鶊D

代碼如何映射到桑基圖

添加有意義的懸停標(biāo)簽

我們都知道plotly繪圖是交互的,我們可以將鼠標(biāo)懸停在節(jié)點(diǎn)和鏈接上以獲取更多信息。

怎么使用Python繪制驚艷的?;鶊D

帶有默認(rèn)懸停標(biāo)簽的?;鶊D

當(dāng)將鼠標(biāo)懸停在圖上,將會(huì)顯示詳細(xì)信息。懸停標(biāo)簽中顯示的信息是默認(rèn)文本:節(jié)點(diǎn)、節(jié)點(diǎn)名稱、傳入流數(shù)、傳出流數(shù)和總值。

例如:

  • 節(jié)點(diǎn)美國(guó)共獲得11枚獎(jiǎng)牌(=39金+41銀+33銅)

  • 節(jié)點(diǎn)金牌共有104枚獎(jiǎng)牌(=美國(guó)39枚,中國(guó)38枚,日本27枚)

如果我們覺得這些標(biāo)簽太冗長(zhǎng)了,我們可以對(duì)此進(jìn)程改進(jìn)。使用hovertemplate參數(shù)改進(jìn)懸停標(biāo)簽的格式

  • 對(duì)于節(jié)點(diǎn),由于hoverlabels 沒有提供新信息,通過傳遞一個(gè)空hovertemplate = ""來去掉hoverlabel

  • 對(duì)于鏈接,可以使標(biāo)簽簡(jiǎn)潔,格式為-

  • 對(duì)于節(jié)點(diǎn)和鏈接,讓我們使用后綴"Medals"顯示值。例如 113 枚獎(jiǎng)牌而不是 113 枚。這可以通過使用具有適當(dāng)valueformat和valuesuffix的update_traces函數(shù)來實(shí)現(xiàn)。

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],
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], 
 # 鏈接的起點(diǎn)或源節(jié)點(diǎn)
 target = [3,4,5,3,4,5,3,4,5], 
 # 鏈接的目的地或目標(biāo)節(jié)點(diǎn)
 value =[ 39, 41, 33, 38, 32, 18, 27, 14, 17], 
 # 鏈接的寬度(數(shù)量) 
 # 鏈接的顏色
 # 目標(biāo)節(jié)點(diǎn):3-Gold4 -Silver5-Bronze
 color = ["lightgreen", "lightgreen", "lightgreen", # 源節(jié)點(diǎn):0 - 美國(guó)
"lightskyblue", "lightskyblue", "lightskyblue", # 源節(jié)點(diǎn):1 - 中國(guó)
"bisque", "bisque", "bisque"],# 源節(jié)點(diǎn):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繪制驚艷的?;鶊D

帶有改進(jìn)的懸停標(biāo)簽的?;鶊D

對(duì)多個(gè)節(jié)點(diǎn)和級(jí)別進(jìn)行泛化相對(duì)于鏈接,節(jié)點(diǎn)被稱為源和目標(biāo)。作為一個(gè)鏈接目標(biāo)的節(jié)點(diǎn)可以是另一個(gè)鏈接的源。

該代碼可以推廣到處理數(shù)據(jù)集中的所有國(guó)家。

還可以將圖表擴(kuò)展到另一個(gè)層次,以可視化各國(guó)的獎(jiǎng)牌總數(shù)。

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 = [], [], [] 

# 第一組鏈接和節(jié)點(diǎn)
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])

# 最后一組鏈接和節(jié)點(diǎn)
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繪制驚艷的?;鶊D

“怎么使用Python繪制驚艷的桑基圖”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI