世衛(wèi)組織的錢從哪里來到哪里去
世界衛(wèi)生組織(WHO)是有影響力的全球性組織之一撩扒,本實驗獲取了 WHO 官網(wǎng)發(fā)布的 2018 - 2019 年財政預(yù)算數(shù)據(jù)波材,對其資金來源及使用情況做了分析桶蝎,研究及可視化了其資金構(gòu)成杠娱、資助項目及資金流向等問題。
輸入并執(zhí)行魔法命令 %matplotlib inline 与学。
%matplotlib inline
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore") # 屏蔽報警
數(shù)據(jù)準(zhǔn)備
本數(shù)據(jù)集來自 WHO彤悔,WHO 在其官網(wǎng)向全球公開透明其資金來源情況以及援助項目情況。本數(shù)據(jù)集統(tǒng)計了在 2018 - 2019 年間指定自愿捐款(Specified voluntary contributions)向 WHO 捐助的資金及 WHO 使用其資金的情況索守。
導(dǎo)入數(shù)據(jù)進(jìn)行初步處理并查看前 5 行晕窑。
import pandas as pd
df=pd.read_excel('https://labfile.oss.aliyuncs.com/courses/3023/World_health_organization_clearning.xlsx')
# 添加各地區(qū)代碼對應(yīng)的地區(qū)全稱
cont_code_name={
'AF':'Africa',
'EM':'Eastern Mediterranean',
'HQ':'Headquarters',
'SE':'South East Asia',
'EU':'Europe',
'WP':'Western Pacific',
'AM':'Americas',
}
df['cont_name']=df['cont'].apply(lambda x:cont_code_name[x])
df.head()
從運行結(jié)果可知,數(shù)據(jù)集由 5 個字段構(gòu)成卵佛,各字段解釋見下表:
世衛(wèi)組織的資金構(gòu)成
根據(jù) WHO 官方網(wǎng)站公開披露的 2018 - 2019 兩年預(yù)算顯示杨赤,WHO 的資金來源主要分為會費分?jǐn)偅ˋssessed contributions)與接受捐贈兩種形式,接受捐贈又分為指定自愿捐款(Specified voluntary contributions)截汪,核心自愿捐助(Core voluntary contributions)疾牲,PIP 捐款(PIP Contributions)。
運行以下代碼衙解,可視化 WHO 的資金來源結(jié)構(gòu)阳柔。
plt.rcParams['figure.figsize'] = (10, 6)
funding_structure = {
'Assessed contributions': 956900000,
'Specified voluntary contributions': 4328057662,
'Core voluntary contributions': 160592410.5,
'PIP Contributions': 178053223,
}
plt.pie(
x=funding_structure.values(),
labels=funding_structure.keys(), # 標(biāo)簽值
explode=[0.1, 0, 0, 0], # 餅圖中每一塊相對中心的偏移
textprops={'size': 20}, # 餅圖中文本格式的設(shè)置
autopct='%.2f%%' # 文本字符顯示格式
)
plt.title('The Contributor Funding Structure of World Health Organization', size=22)
從運行結(jié)果可知,WHO 成員國會費占其總預(yù)算比例相對較低蚓峦,只有 17%舌剂,剩余部分全部來源于自愿捐款,而本實驗數(shù)據(jù)集涉及的指定自愿捐款(Specified voluntary contributions)占到所有捐款的比例最高暑椰,為總預(yù)算的 76.96% 霍转。
資助組織及被資助項目結(jié)構(gòu)
按資金流向分組聚合,并將聚合結(jié)果歸一化后拼接一汽。
import numpy as np
# 篩選出流入 WHO 的資金避消,按資助組織進(jìn)行資助金額的求和并逆序排序
funding_from = df.loc[df['direction'] == 'from'].groupby(
['orgs'])['money'].sum().sort_values(ascending=False)
# 將資金歸一化處理
funding_from = funding_from/np.sum(funding_from)
# 同樣的方式處理被資助項目
funding_to = df.loc[df['direction'] == 'to'].groupby(
['orgs'])['money'].sum().sort_values(ascending=False)
funding_to = funding_to/np.sum(funding_to)
# 將兩個Series對象按列拼接
funding_from_to = pd.concat([funding_from, funding_to])
# 展示處理后的數(shù)據(jù)
funding_from_to
資助組織及被資助項目金額經(jīng)過歸一化后,其求和值均為 1 角虫,因此將其可視化到餅圖時沾谓,每一部分的占比會被壓縮到一半(因為餅圖的總百分比是 100%委造,但是兩部分求和結(jié)果是 200%)戳鹅。例如,美國(United States of America)在所有資助組織中資助的金額占比為 15.17%昏兆,但經(jīng)拼接后在 funding_from_to 數(shù)據(jù)并可視化到餅圖后枫虏,其占比將縮小至 7.585%,因此為了顯示 15.17% 數(shù)據(jù),需要在 plt.pie 接口參數(shù) autopct 傳入格式化函數(shù) autopct_fun隶债,該函數(shù)將顯示的百分比數(shù)據(jù)擴(kuò)大為原值的 2 倍腾它。
plt.rcParams['figure.figsize'] = (15, 15)
def autopct_fun(x):
return '%.2f%%' % (2*x)
plt.pie(x=funding_from_to,
labels=funding_from_to.index,
textprops={'size': 17},
autopct=autopct_fun)
plt.title(
'Where Does the World Health Organization Contributor Funding From and Go ?', size=28)
上面的圖中因為類別太多,導(dǎo)致 label 都擠在一起看不清死讹。下面我們對上面的圖像進(jìn)行簡化瞒滴。 具體的 index 的編號可以通過 np.where 來找到。
plt.rcParams['figure.figsize'] = (14, 7)
def autopct_fun(x):
if 2*x < 8:
return None
else:
return '%.2f%%' % (2*x)
plt.pie(x=funding_from_to.values,
labels=list(funding_from_to.index[0:4]) + ['' for i in funding_from_to.index[4:301]] + list(
funding_from_to.index[301:304]) + ['' for i in funding_from_to.index[304:]],
textprops={'size': 13},
autopct=autopct_fun)
plt.title(
'Where Does the World Health Organization Contributor Funding From and Go ?', size=17)
從輸出結(jié)果可以看出:
WHO 最大的捐助國為美國( United States of America )赞警,占比 15.18%妓忍,其次是蓋茨基金會( Bill & Melinda Gates Foundation ),占比 12.12%愧旦,排名第三的是全球疫苗和免疫聯(lián)盟( GAVI Alliance )世剖,占比 8.19%;
WHO 最大的投資項目為根除脊髓灰質(zhì)炎( Polio eradication )笤虫,占比 26.55%旁瘫,其次是提升獲得基本保健和營養(yǎng)服務(wù)( Increase access to essential healthand nutrition services ),占比 12.05%琼蚯,排名第三的是可預(yù)防疾病疫苗( Vaccine-Preventable Diseases )酬凳,占比 8.96%。
不同地區(qū)的資助項目
本實驗的目的是繪制兩個半圓形餅圖遭庶,內(nèi)半圓表示各個被資助地區(qū)的百分占比粱年,外半圓表示各個地區(qū)對應(yīng)項目的百分占比,且須做到內(nèi)半圓地區(qū)塊與外半圓項目塊顏色的主色調(diào)完全對應(yīng)罚拟。由于本例相對復(fù)雜台诗,因此分步驟進(jìn)行繪圖解釋:
生成內(nèi)半圓數(shù)據(jù)集
選擇資金流向為 to 的數(shù)據(jù),以地區(qū)進(jìn)行資金聚合赐俗、逆序排序并歸一化,查看前 5 行數(shù)據(jù)阻逮。
funding_cont_to = df.loc[df['direction'] == 'to'].groupby(
['cont'])['money'].sum().sort_values(ascending=False)
funding_cont_to = funding_cont_to/np.sum(funding_cont_to)
funding_cont_to.head()
內(nèi)半圓的顏色變化序列
Matplolib 默認(rèn)顏色序列為 TABLEAU_COLORS叔扼,可通過 cs.to_rgba 將其轉(zhuǎn)變?yōu)?rgba 顏色元組(plt.pie 接口需要的顏色參數(shù)類型為 rgba 或者 rgb 格式)事哭,內(nèi)半圓仍然采用默認(rèn)序列的顏色。
import matplotlib.colors as cs
start_colors=[cs.to_rgba(value) for value in cs.TABLEAU_COLORS.values()]
start_colors
外半圓的顏色變化序列
外圈的項目顏色塊由其對應(yīng)的內(nèi)圈的主題顏色確定瓜富,例如對于非洲 AF 地區(qū)的項目与柑,如果 AF 的色塊顏色為藍(lán)色谤辜,則非洲區(qū)所有項目顏色均為藍(lán)色蓄坏,但為了將項目進(jìn)行有效區(qū)分,需要將各項目顏色進(jìn)行漸變色設(shè)置涡戳,其原理是進(jìn)行主題色到白色的線性插值脯倚。
colors = []
for i, c in enumerate(funding_cont_to.index):
# WHO向每個大區(qū)投入的項目,按降序排序
funding_projection = df.loc[(df['direction'] == 'to') & (df['cont'] == c), [
'orgs', 'money']].sort_values('money', ascending=False)
# 獲取每個地區(qū)總項目數(shù)
color_nums = len(funding_projection)
# 每個地區(qū)對應(yīng)項目的主題顏色
r, g, b, a = start_colors[i]
# 根據(jù)主題顏色線性地生成由該主題顏色到白色的序列漸變色
for r_new, g_new, b_new in zip(np.linspace(r, 1, color_nums), np.linspace(g, 1, color_nums), np.linspace(b, 1, color_nums)):
colors.append((r_new, g_new, b_new, 1.0))
colors[:5]
外半圓的標(biāo)簽設(shè)置
由于外半圓項目數(shù)量較大胳岂,因此每個地區(qū)只顯示排名前 1 的項目舔稀,其余項目不作顯示。
labels = []
for i, c in enumerate(funding_cont_to.index):
funding_projection = df.loc[(df['direction'] == 'to') & (df['cont'] == c), [
'orgs', 'money']].sort_values('money', ascending=False)
show_top = 1
label = np.append(funding_projection['orgs'][:show_top],
['']*(len(funding_projection)-show_top))
labels = np.append(labels, label)
labels[:5]
生成外半圓數(shù)據(jù)集
funding_proj_to = pd.DataFrame()
for i, c in enumerate(funding_cont_to.index):
funding_projection = df.loc[(df['direction'] == 'to') & (df['cont'] == c), [
'orgs', 'money']].sort_values('money', ascending=False)
# 合并所有地區(qū)的數(shù)據(jù)
funding_proj_to = pd.concat([funding_proj_to, funding_projection])
funding_proj_to.set_index(['orgs'], inplace=True)
funding_proj_to = funding_proj_to/np.sum(funding_proj_to)
funding_proj_to.head()
繪圖
半圓圖的繪制原理:當(dāng)傳入 plt.pie 接口參數(shù) x 的求和值小于 1 時产园,差額部分將形成餅圖的缺口什燕,因此將歸一化的 x 數(shù)據(jù)乘以 0.5 即可獲得半圓竞端,同理,此時的百分占比被壓縮成原比例的一半技俐,需要通過 autopct_fun 函數(shù)將其顯示比例數(shù)據(jù)作修正统台。
plt.rcParams['figure.figsize'] = (15, 15)
def autopct_fun(x):
return '%.2f%%' % (2*x)
# 外圈繪制項目
plt.pie(x=0.5*funding_proj_to, # 當(dāng)x求和小于1時贱勃,餅狀圖則按比例顯示,剩余部分為白色贵扰,此處將數(shù)據(jù)乘以 0.5戚绕,繪制結(jié)果為半圓
labels=labels,
radius=1, # 餅圖半徑
wedgeprops={'width': 0.4}, # 餅的徑向?qū)挾? colors=colors, # 每個色塊的顏色,此處顏色的格式是 rgba 元組
textprops={'size': 17},
autopct='')
# 內(nèi)圈繪制地區(qū)
plt.pie(x=0.5*funding_cont_to,
labels=funding_cont_to.index,
radius=0.45,
pctdistance=0.8, # 餅狀圖中表示 比例數(shù)據(jù)的文本 相對中心的位置
wedgeprops={'width': 0.3},
colors=cs.TABLEAU_COLORS,
textprops={'size': 17},
autopct=autopct_fun)
plt.ylim(0.5, 1.2)
plt.title('The Funded Zones and The Top 1 Important Funded Programs', size=30)
從輸出結(jié)果可以看出恰画,已實現(xiàn)了地區(qū)與地區(qū)項目的顏色對應(yīng),且地區(qū)項目由主題色到白色進(jìn)行漸變顯示瓷马。下表列出了每個地區(qū)排名前 2 的被資助項目:
非洲被資助項目的相對比例
非洲毫無疑問是 WHO 項目重點投資地區(qū),以該地區(qū)最大的投資項目為對比對象片林,研究其他項目相對其所占比例怀骤。通過數(shù)據(jù)聚合并逆序排序的方式,獲取最大項目的值弓摘,以該值為分母進(jìn)行數(shù)據(jù)的歸一化痕届,此處為美觀考慮研叫,將最大項目的弧度設(shè)置為半圓。
funding_to = df.loc[(df['direction'] == 'to') & (df['cont'] == 'AF')].groupby(
['orgs'])['money'].sum().sort_values(ascending=False)
funding_to = funding_to/np.sum(funding_to)
first_large = funding_to[0]
# 計算各項目相對最大投資項目的百分比渊啰,最大投資項目比例設(shè)定為 0.5申屹,目的是為了繪制半圓
funding_to_related = funding_to/first_large*0.5
funding_to_related.head(10).index[:10]
通過調(diào)節(jié)接口中圓圈的半徑 radius 及寬度 wedgeprops 兩個參數(shù)哗讥,將非洲地區(qū)被投資項目逐環(huán)式地向內(nèi)繪制,最外徑為投資額最大的項目车酣,依次向內(nèi)索绪,項目投資額逐漸遞減。
width = 0.03
fig, ax = plt.subplots(1, 1, figsize=(15, 15))
for i, projection_percent in enumerate(funding_to_related):
ax.pie(x=projection_percent,
startangle=90,
radius=1.0-i*width,
labels=['a'], # 輸入圖例文本占位符
autopct='',
textprops={'size': 0},
wedgeprops={'width': width}
)
# 修改圖例為各個項目的項目名稱
h, l = ax.get_legend_handles_labels()
plt.legend(handles=h,
labels=list(funding_to_related.index),
ncol=2,
bbox_to_anchor=(0.55, 0.85),
loc='upper left',
frameon=False,
fontsize=20)
plt.title('Funded Programs of Africa Weights Related to Polio Eradication',
fontsize=30,
ha='left')
運行結(jié)果可以看到各個項目相對最大項目的比例娘摔,可以看出各項目相對根除骨髓灰質(zhì)炎項目的相對比例大小凳寺,整理后,相對比例如下表所示:
資助項目的資金規(guī)模分布
根據(jù)被投資項目的項目金額逆趋,將項目分成小于 1 千萬闻书,1 千萬- 1 億脑慧,大于 1 億三個等級(單位:美金)。
funding_programs = df.loc[df['direction'] == 'to'].copy()
# 1M=100萬=1e6
bins = [funding_programs['money'].min(), 1e7, 1e8,
funding_programs['money'].max()]
funding_programs['program_structure'] = pd.cut(funding_programs['money'],
bins=bins,
labels=[
'<10M', '10M-100M', '>100M']
)
funding_programs['money'] = funding_programs['money'] / \
np.sum(funding_programs['money'])
funding_programs.head()
按投資項目金額及所在地區(qū)坑律,研究各地區(qū)項目資金結(jié)構(gòu)脾歇。
# 設(shè)定隨機(jī)數(shù)種子
np.random.seed(121)
row_names = ['<10M', '10M-100M', '>100M']
col_names = ['AF', 'EM', 'HQ', 'EU', 'SE', 'WP', 'AM']
fig, axs = plt.subplots(
nrows=len(row_names),
ncols=len(col_names),
figsize=(len(row_names)*7, len(col_names)*1))
for i, s in enumerate(row_names):
for j, c in enumerate(col_names):
ax = axs[i, j]
x = funding_programs.loc[(funding_programs['cont'] == c) & (
funding_programs['program_structure'] == s)]['money'].sum()
# 繪制淺色背景
ax.pie([1], radius=0.8, colors=[(0.97, 0.97, 0.97)])
# 繪制深色主體
ax.pie(x=[x],
startangle=90,
radius=1.0,
labels=['%.2f%%' % round(x*100, 2)],
autopct='%.2f%%',
colors=np.random.random(size=(1, 3)), # 隨機(jī)生成一個顏色元組(rgb元組)
textprops={'size': 0},
)
ax.legend(frameon=False, fontsize=15)
ax.set_title(label='%s : %s' % (c, s), size=15)
fig.suptitle('The Funded Programs Budget Structure of Different Zones', size=20)
從輸出結(jié)果可以看出:
超大金額(大于 1 億)的投資項目集中在 Africa藕各,Eastern Mediterranean 兩個地區(qū)焦除,Europe 等 4 個地區(qū)沒有該規(guī)模項目;
中等規(guī)模項目集中在 Headquarters 地區(qū)乌逐。
被資助項目的資金規(guī)模分布-樹形地圖
!pip install pyecharts==1.7.1
另一種可視化結(jié)構(gòu)的繪圖對象為 pyecharts 包提供的 TreeMap 類创葡,與傳統(tǒng)的餅圖不同灿渴,TreeMap 用一個個的方格表示各元素相對整體的比例。
from pyecharts import options as opts
from pyecharts.charts import TreeMap
funding_to = df.loc[df['direction'] == 'to'].groupby(
['orgs'])['money'].sum().sort_values(ascending=False)
funding_to = funding_to/np.sum(funding_to)
# 生成 TreeMap 數(shù)據(jù)蹬挤,該數(shù)據(jù)為 json 格式
funding_to_treemap = [{'value': value, 'name': name}
for name, value in zip(funding_to.index, funding_to)]
tree = TreeMap()
tree.add("Funded Budget",
funding_to_treemap,
label_opts=opts.LabelOpts(position="inside", font_size=12),
drilldown_icon=" ",
leaf_depth=1)
tree.set_global_opts(
title_opts=opts.TitleOpts(
title="The Funded Programs Budget Structure",),
legend_opts=opts.LegendOpts(
pos_top='5%', textstyle_opts=opts.TextStyleOpts(font_size=15))
)
tree.render_notebook()
從輸出結(jié)果可以看出前 5 類投資項目將近占到了總項目投資額的 60% 以上焰扳。
帶鉆取結(jié)構(gòu)的樹形圖
TreeMap 類還提供了數(shù)據(jù)鉆取功能,原理是傳入的數(shù)據(jù)文件增加一個 children 字典項扫茅,children 的值為需要被鉆取的 TreeMap 數(shù)據(jù)育瓜,以下代碼生成了帶鉆取功能的數(shù)據(jù)。
數(shù)據(jù)準(zhǔn)備
funding_to = df.loc[df['direction'] == 'to'].groupby(
['cont_name', 'orgs'], as_index=False)['money'].sum()
funding_to['money'] = funding_to['money']/np.sum(funding_to['money'])
funding_to_treemap = [
{'value': funding_to.loc[funding_to['cont_name'] == name]['money'].sum(),
'name': name,
'children':[
{
'value': funding_to.loc[(funding_to['cont_name'] == name) & (funding_to['orgs'] == org)]['money'].sum(),
'name': org,
}
for org in list(set(funding_to.loc[funding_to['cont_name'] == name, 'orgs']))
]
}
for name in list(set(funding_to['cont_name']))
]
繪圖
tree = TreeMap()
tree.add("Funded Budget",
funding_to_treemap,
label_opts=opts.LabelOpts(position="inside", font_size=20),
drilldown_icon=" ",
leaf_depth=1 # 初始化圖形時愕鼓,顯示第一層(即最高級)
)
tree.set_global_opts(
title_opts=opts.TitleOpts(
title="The Funded Programs Budget Structure of Different Zones",),
legend_opts=opts.LegendOpts(
pos_top='5%', textstyle_opts=opts.TextStyleOpts(font_size=15))
)
tree.render_notebook()
運行以上代碼,輸出的是地區(qū)級的結(jié)構(gòu)圖册倒,當(dāng)鼠標(biāo)點擊其中一塊區(qū)域時磺送,樹形圖向下鉆取該區(qū)域子項目的結(jié)構(gòu)圖,可通過圖最下面的層級按鈕可以回到上一級崇呵。
被資助項目的資金規(guī)模分布-太陽花圖
同樣的數(shù)據(jù)結(jié)構(gòu)傳入 Sunburst 類域慷,可以獲得帶有鉆取功能的太陽花圖汗销,太陽花圖帶有兩個餅圖,內(nèi)部餅圖代表父級的結(jié)構(gòu)組成叠骑,點擊任一顏色塊削茁,數(shù)據(jù)向下鉆取到該層級下子項的餅圖茧跋。
from pyecharts.charts import Sunburst
funding_to = df.loc[df['direction'] == 'to'].groupby(
['cont_name', 'orgs'], as_index=False)['money'].sum()
funding_to['money'] = funding_to['money']/np.sum(funding_to['money'])
# 數(shù)據(jù)結(jié)構(gòu)與樹形圖完全一致
funding_to_treemap = [
{'value': funding_to.loc[funding_to['cont_name'] == name]['money'].sum(),
'name': name,
'children':[
{
'value': funding_to.loc[(funding_to['cont_name'] == name) & (funding_to['orgs'] == org)]['money'].sum(),
'name': org,
}
for org in list(set(funding_to.loc[funding_to['cont_name'] == name, 'orgs']))
]
}
for name in list(set(funding_to['cont_name']))
]
sun = Sunburst()
sun.add(
"",
data_pair=funding_to_treemap,
highlight_policy="ancestor",
radius=[0, "95%"],
sort_="null",
label_opts=opts.LabelOpts(is_show=False, position='inside', font_size=5),
levels=[
{ # 外圈設(shè)置
"r0": "65%", # 內(nèi)圈半徑
"r": "95%", # 外圈半徑
"itemStyle": {"borderWidth": 2},
"label": {"rotate": "tangential"},
},
{ # 內(nèi)圈設(shè)置
"r0": "25%",
"r": "45%",
},
],
)
sun.set_global_opts(title_opts=opts.TitleOpts(title="The Funded Programs Budget Structure of Different Zones"))
sun.set_series_opts(label_opts=opts.LabelOpts(formatter="厌衔"))
sun.render_notebook()
世衛(wèi)組織的資金流向
餅狀圖是表達(dá)組成關(guān)系或者總分關(guān)系的最佳繪圖對象,樹形圖和太陽花圖在餅圖的基礎(chǔ)上睬隶,增加了交互式地鉆取功能,實現(xiàn)了不同層級結(jié)構(gòu)的總分表達(dá)银萍。在之前的實驗中恤左,我們借助這幾類對象研究了世衛(wèi)組織的資金來源飞袋、資助項目,以下我們進(jìn)一步研究其資金的流向巧鸭。
描述流向的繪圖對象主要是 筛偃裕基圖,梢拐裕基圖早期的應(yīng)用主要是能量分布乡革,后期在金融領(lǐng)域大放異彩署拟,再后來被廣泛應(yīng)用到經(jīng)管領(lǐng)域。尚陌基圖將帶有流向特征的節(jié)點通過一定寬度的線連接起來馒铃,線的疏密代表任意兩節(jié)點的能量強(qiáng)弱。赏拗常基圖繪圖的主要難點在于數(shù)據(jù)準(zhǔn)備工作议谷,以下分布展示其過程:
將資金量小于閾值的組織或者項目設(shè)置為其他類別
為減少桑基圖可視化的節(jié)點數(shù)量芬首,避免圖片過大反而帶來閱讀困難郁稍,將所有資助組織和被資助項目金額小于 1000 萬的均設(shè)置成其他資助者(other contributions)或其他項目(other programs)。
data = df.copy()
limit_money = 1e7
data['orgs_adjust'] = data['orgs']
data.loc[(data['direction'] == 'from') &
(data['money'] <= limit_money), 'orgs_adjust'] = 'other contributions'
data.loc[(data['direction'] == 'to') &
(data['money'] <= limit_money), 'orgs_adjust'] = 'other programs'
data.head()
數(shù)據(jù)構(gòu)建
苫肿牛基圖接口主要傳入兩個數(shù)據(jù)财破,一個為 nodes狈究,一個為 links盏求。nodes 表示需要可視化的節(jié)點碎罚,此處 nodes 由各個組織名稱和各個地區(qū)名稱構(gòu)成,對其進(jìn)行去重和拼接拯勉;links 為一個列表憔购,列表中每個元素為一個字典,由 source导绷,target屎飘,value 三個鍵構(gòu)成钦购,分別代表起始節(jié)點、結(jié)束節(jié)點和連接兩節(jié)點的能量值葵萎,source 和 target 須包含在 nodes 節(jié)點列表中。節(jié)點連接一共分成兩個部分锡足,出資國家與被資助地區(qū)為資金流入關(guān)系壳坪,被資助地區(qū)與被資助項目為資金流出關(guān)系爽蝴,因此在生成節(jié)點連接數(shù)據(jù)集時需要考慮 source 和 target 的方向,以下代碼生成了用于删藕ⅲ基圖接口的數(shù)據(jù)发框。
sankey_value='money'
# 去重后拼接
node_lists = np.append(np.unique(data['orgs_adjust']),(np.unique(data['cont'])))
nodes = [
{
'name': node
}
for node in node_lists
]
links = [
{
"source": s,
"target": t,
"value": v
}
for s, t, v in zip(data.loc[data['direction'] == 'from', 'orgs_adjust'],
data.loc[data['direction'] == 'from', 'cont'],
data.loc[data['direction'] == 'from', sankey_value],
)
]+[
{
"source": s,
"target": t,
"value": v
}
for t, s, v in zip(data.loc[data['direction'] == 'to', 'orgs_adjust'],
data.loc[data['direction'] == 'to', 'cont'],
data.loc[data['direction'] == 'to', sankey_value],
)
]
擅饭撸基圖的繪制
桑基圖的接口調(diào)用方式和大多數(shù) pyecharts 接口類似她君。運行以下代碼葫哗,可生成世衛(wèi)組織 2018 -2019 年指定自愿捐款的資金流向圖劣针,該圖細(xì)致地展示了每一筆資金的使用,在 WHO 官網(wǎng)上鸟廓,也有一張類似的圖辣苏,該圖生動地公開了 WHO 經(jīng)費使用情況稀蟋,便于讀者了解 WHO 的資金預(yù)算流向情況。
from pyecharts.charts import Sankey
init_opts=opts.InitOpts(width='1000px',height='1000px')
sankey = Sankey(init_opts=init_opts) # 初始化圖片的寬度和高度
sankey.add(
series_name="",
nodes=nodes,
links=links,
node_gap=7, # 節(jié)點間距
label_opts=opts.LabelOpts(position='right',font_size=15), # 設(shè)置節(jié)點文本
itemstyle_opts=opts.ItemStyleOpts(border_width=2), # 設(shè)置節(jié)點寬度
linestyle_opt=opts.LineStyleOpts(color="source", width=2,curve=0.5, opacity=0.5), # 設(shè)置線型
tooltip_opts=opts.TooltipOpts(trigger_on="click") # 設(shè)置交互方式
)
sankey.set_global_opts(
title_opts=opts.TitleOpts(title="The Funding Budget Flows of Specified Voluntary Contributions of WHO in Year 2018 - 2019"),
)
sankey.render_notebook()