通過一張圖就能看懂世界石油分佈?Python爬蟲輕鬆搞定!

CDA數據分析師 出品

2020年的3月註定將載入史冊。一邊是新冠肺炎疫情在全世界快速擴散,另一邊是掌控着世界40%以上油氣產量的巨頭們撕破臉皮。

面對在OPEC+會議中堅持不再減產的俄羅斯,沙特阿拉伯決意提升石油產能搶佔市場,石油價格戰毫無徵兆地開打。國際原油價格出現大幅波動。3月9日,黑色星期一,世界油價劇烈殺跌,跌幅超過30%。

那麼作爲現代工業裏最重要的命脈,

世界石油產量分佈究竟如何?

誰纔是石油界的真正王者呢?

中國的石油儲量什麼水平?

今天我們就教你

用一張圖看懂世界石油分佈。

01

展現數據流動的利器
桑基圖

這裏我們用到的是桑基圖(Sankey diagram)。

也許你沒見過這張圖,這算是一個比較小衆的圖表。

我們可以看到桑基圖主要由邊、流量和支點組成,其中邊代表了流動的數據,流量代表了流動數據的具體數值,節點代表了不同分類。邊的寬度與流量成比例地顯示,邊越寬,數值越大。

02

桑基圖的發展
最早的桑基圖

最著名的桑基圖是查爾斯·米納德(Charles Minard)繪製的1812年拿破崙俄國戰役地圖。這張戰役地圖將一張桑基圖疊加到一張地圖上,是一張流程圖與地圖結合的圖表。

桑基圖中的粉色部分描繪了拿破崙軍隊在歐洲的移動和數量變化情況,顯示了在1812年6月,拿破崙帶領了42萬人入侵俄羅斯。然而隨着戰爭不斷深入,軍隊人數一路減少,到了戰敗撤退時,只剩下1萬人。這張最早的桑基圖創建於1869年,但它那時候還不叫桑基圖,直到29年後一位愛爾蘭船長的出現。

桑基圖的命名

1898年,愛爾蘭船長馬修·亨利·菲尼亞斯·里亞爾·桑基(Matthew Henry Phineas Riall Sankey)使用了這種類型的圖表展示了蒸汽的能源效率。與此同時,這個圖也以船長的名字命名爲“桑基圖”。

當時在這張黑白圖表只顯示了一種類型的流動(如蒸汽); 使用不同顏色能表示不同類型的流動,從而表達出多種變量。

隨着時間的推移,桑基圖逐漸成爲科學和工程中用來表示熱平衡、能量流、物質流動的標準模型。

比起普通的流程圖或條形圖,桑基圖體現的數據流動清晰且美觀,因此在能源管理、設施管理、過程工程和過程控制等數據可視化方面,桑基圖也越來越受歡迎。

03

桑基圖的用例

桑基圖一個最大的特點就是,無論數據怎麼流動,桑基圖的總數值保持不變,堅持數據的“能量守恆”。

汽車的能量消耗

在這個桑基圖中,你可以看到汽車的能量平衡。除了車輪行駛所消耗的能量之外,還有很大一部分能量損失了,尤其是熱量損失。此外,還有水泵、轉向支持等定額外的能源消耗。圖表中的流量可以用顏色來區分,它們的寬度與所代表的流量成比例。

國家的能源平衡

在地區或國家的能源平衡經常使用桑基圖繪製能源流程圖。從而可以清晰的看出能源和能源來源的不同用途。

這張圖是2011年馬來西亞的能源平衡。圖中流動表示的是“百萬噸石油當量”(Mtoe)。

法國公關管理部門資金來源

法國公共管理部門就曾用一張桑基圖理清了他們的收支資金來源,以及他們是如何分配這些資金的。最左邊的支點代表了不同的資金來源,包括社會、個人稅收等。這些資金在彙總到法國的四大公共管理部門後,被再分配到交通、環境保護、住房、教育、文化等各個領域。

04

教你用Python
輕鬆繪製世界石油分佈圖

可見在表示數據流動方面,桑基圖十分清晰而且美觀。前面我們展示了一張世界石油產量前30國家分佈桑基圖,下面我們教你就用pyecharts來實現它。

如果你沒有安裝pyecharts,可以使用以下代碼在終端進行pip安裝。

pip install pyecharts

首先需要導入我們需要使用的包,其中pandas用於數據整理,pyecharts用於繪圖。

import pandas as pd 
from pyecharts.charts import Sankey
from pyecharts import options as opts 

然後使用pandas讀入數據,所使用數據來自於BP世界能源統計年鑑-2019版,整理之後的數據使用數據框的形式進行存儲,其中state表示國家名稱,continent表示大洲名,num表示石油產量(單位百萬噸)

df1 = pd.read_excel('石油產量排名.xlsx')
df1.head() 

桑基圖在pyecharts中通過Sankey方法實現,它接受兩個外部輸入。一個是所有類別的集合-nodes,一個是子類、父類、數據的三方集合-links。也就是說,首先你要把數據轉換成Sankey可以接受的形式,下面這個是官網的示例的數據格式:

下面我們寫個簡單的循環語句,將數據轉換成nodes和links形式:

# 產生節點
nodes = []

for i in set(pd.concat([df1.state, df1.continent])):
    dic_ = {}
    dic_['name'] = i 
    nodes.append(dic_) 

# 產生鏈接
links = []

for x, y, z in zip(df1.state, df1.continent, df1.num):
    dic_ = {}
    dic_['source'] = x
    dic_['target'] = y 
    dic_['value'] = z 
    links.append(dic_) 

準備好nodes和links後,就可以調用Sankey函數進行繪圖,你可以通過配置項otps來設置圖表的顏色、標籤、標題等信息,具體細節可以去官網查詢,這裏不做贅述。

colors = ['#54B4F9', '#F29150', '#FF7BAE', '#D69AC0', '#485CE0', '#28BE7A'] 

s = Sankey(init_opts=opts.InitOpts(width='1350px', height='1350px')) 
s.set_colors(colors)
s.add('sankey', 
      nodes, 
      links, 
      pos_left='10%',
      pos_right='60%',
      linestyle_opt=opts.LineStyleOpts(opacity=0.2, curve=0.5, color='source'), 
      itemstyle_opts=opts.ItemStyleOpts(border_width=1, border_color="#aaa"),
      tooltip_opts=opts.TooltipOpts(trigger_on="mousemove"),
      is_draggable=True,
      label_opts=opts.LabelOpts(position="left", 
                                font_family='Arial', 
                                margin=10,
                                font_size=13, 
                                font_style='italic')
     ) 

s.set_global_opts(title_opts=opts.TitleOpts(title='世界石油產量top30國家分佈'))  
s.render() 

生成html文件後,直接通過瀏覽器打開即可,就可以看到能交互的桑基圖了,是不是效果十分驚豔呢?快來自己試試吧!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章