Python——利用 graphtool 進行圖的可視化處理
前言
graph_tool 這是個專門用於對圖進行可視化的 Python 庫。雖然網上中文資料不足,但是他的英文文檔還是非常全面的,很多設計的小細節也在文檔里提及了,非常簡單容易上手。下面就從一個初學者的記錄下我的學習歷程。
安裝
雖然是個python庫,但是畢竟是要做大量數據計算的,因此graphtool在底層使用了Boost, CGAL 和 expat這幾個C++庫(Boost是擴展的標準庫,CGAL是一個計算幾何演算法庫,expat是一個XML解析器)。這就導致了使用通常的pip和easyinstall不太好直接安裝。正確的安裝姿勢大概有三種:
- 使用Docker
- 源碼安裝
- 各個Linux版本的包管理器
這裡主要參考 graph-tool installation (http://t.cn/R8tunJ7)的各種安裝說明。從最基本的源碼安裝,到封裝好的包管理器安裝,再到最萬金油的docke安裝一應俱全。
看上去一片美好。然而真正用的時候發現,如果使用 docker,官方提供的鏡像還是太過龐大,用起來還是太臃腫了;如果採用更新源+包管理器安裝的化,要是系統的版本比較新還好,要是系統版本老了,就會報各種依賴不足的問題。。。最坑爹的是,即使採用源碼安裝的方式,由於開發人員比較勤快,經常更新技術,很多庫都需要較新的版本,容易導致老的機器上無法編譯,而且由於項目源碼是託管在他自己搭的 git 伺服器上,這個伺服器還很坑,舊的版本經常下不下來。。。最近不知道為什麼官網的伺服器崩了,還好我之前下了源碼,於是把他 fork 到了我的 github 上,做個備份。
不過還好,雖然我的伺服器比較舊,但是我的台式機比較新,沒啥問題。。。
函數結構
這個項目的文檔非常詳盡,可以參考他的 quickstart(http://t.cn/R8tuJQh),類的API(http://t.cn/R8tuWPu) 在這裡。下面稍微整理下大概用途,方便查找:
graph_tool主要用於是圖的載入、構建、刪除、持久化、迭代graph_tool.centrality主要用於計算與圖的中心度相關的信息graph_tool.clustering主要用於計算圖的各種聚類係數graph_tool.collection保存了十幾個供參考的數據集graph_tool.correlations主要用與計算各種相關度信息graph_tool.draw封裝了一些常用的繪圖演算法graph_tool.flow處理圖的最大流最小割一類的問題graph_tool.generation主要用於預先生成一些圖,比如完全圖,隨機圖,晶格圖等等graph_tool.inference主要用於推斷圖的社區結構graph_tool.stats主要用於圖的簡單直方圖統計等信息graph_tool.topology主要包裝了圖的拓撲性質,比如最短路,最小生成樹,拓撲排序等等graph_tool.util主要是一些節點和邊的查找方法
簡單說明
圖的構建
- graph-tool 支持有向圖和無向圖,默認是無向圖,他將節點用一個編號表示,邊用開始節點和終結點的編號來表示。節點編號下標從0 開始遞增,並始終從 0 開始保持連續。
- 當我們刪除一個節點時,實際上是將這個節點與最後一個節點交換索引,然後將總的編號減一。因此當我們迭代刪除的時候,要按照節點編號逆序遍歷刪除。
- graph-tool 為方便保存圖的信息,採用的是壓縮的 xml 來進行圖的持久化存儲,用這個格式來保存圖還是比較高效的,我們要率先考慮。
- 使用這個庫的時候我們盡量不要寫循環語句,比如節點度數的統計信息等。因為就和 numpy 一樣,絕大多數需要循環的操作他都提供了並且做了優化,我們需要做的就是找到這個函數。
PropertyMap 對象
這個對象是 graph_tool 封裝的一個映射工具,文檔在這裡(http://t.cn/R8tuUI3),以後經常會用到。他其實是對 C++ 中的 Map 進行的一個封裝,鍵的類型被限定為了』e』,』v』,』g』,而值可以映射為 int,float,vector 等多種 c++ 類型,用法如下:
import graph_tool.all as gtng=gt.price_network(200)nprop_v=g.new_vertex_property("int")#創建一個節點到int的映射n#prop_e=g.new_edge_property("int")#創建一個邊到int的映射n#prop_g=g.new_graph_property("int")#創建一個圖到int的映射nprop_v.a=np.ones(g.num_vertices()) #為prop_v賦值n#print prop_v.a#直接獲取映射數組n#print prop_v[2]#按下標取值n#print prop_v.value_type()#值的類型n#print prop_v.key_type()#鍵的類型 n
我們也可以直接把 PropertyMap 跟 Graph 綁定:
g.properties[("e", "foo")] = g.new_edge_property("vector<double>")ng.vertex_properties["foo"] = g.new_vertex_property("double")ng.vertex_properties["bar"] = g.new_vertex_property("python::object")ng.graph_properties["gnat"] = g.new_graph_property("string", "hi there!") n
繪圖方法
我的目的是畫圖,那麼我就重點研究了下用來畫」圖」的函數graph_draw。這個函數必選參數只有一個,但是可選參數卻有十幾個,我們選幾個重要的一一討論。
下面是函數原型:
graph_tool.draw.graph_draw(g, pos=None, vprops=None, eprops=None, vorder=None, eorder=None, nodesfirst=False, output_size=(600, 600), fit_view=True, inline=False, mplfig=None, output=None, fmt=auto, **kwargs) n
必備參數
必備的參數肯定是 g,是指我們需要畫的 Graph 對象。
pos 參數
pos 參數是指我們通過一些布局演算法計算出來的對於每一個節點的坐標,是一個 PropertyMap 對象。這個 PropertyMap 對象其實就是一個映射,每一個節點的下標對應了該節點的 x,y 坐標。這個對象是通過布局演算法生成的就行了。默認情況下我們用的是 sfdp_layout() 方法來生成這一系列坐標。
vorder,eorder,nodefirst 參數
這些參數控制的是繪圖的順序,主要是考慮了一些點線的覆蓋問題。
output 參數
這個參數指定的是文件的輸出文件名和格式,可以根據後綴判斷,支持png,svg,pdf,ps 四種文件格式。當然也可以用 fmt 參數直接指定格式。通常情況下 png 方便顯示,但是容易失真。pdf 和 svg 是基於矢量的,放大不失真。
有趣的是如果不指定這個參數,那麼他會生成一個可以交互的界面:
這個界面至少有下面的功能:
- 點擊一個節點,左下角會顯示這個節點的下標
- 點擊一個節點,他會高亮與之相鄰的節點
- 我們可以對圖片進行放大,縮小,旋轉
- 我們可以拖動節點從而改變圖的形狀
- 對圖片進行修改後,在我們關閉界面之後,修改後的布局會被更新到 pos 參數里
vertex_*,edge_*屬性
這些屬性可以指定具體畫圖的樣式,樣式表可以參見文檔(http://t.cn/R8tmel3),下面用幾個例子說明。
import graph_tool.all as gtnimport numpy as npng = gt.price_network(1500)ndeg = g.degree_property_map("in")ndeg.a = 4 * (np.sqrt(deg.a) * 0.5 + 0.4)nebet = gt.betweenness(g)[1]nebet.a /= ebet.a.max() / 10.neorder = ebet.copy()neorder.a *= -1npos = gt.sfdp_layout(g)ngt.graph_draw(g, pos=pos, vertex_size=deg, vertex_fill_color=deg,n vorder=deg,edge_color=ebet, eorder=eorder, edge_pen_width_=ebet,n output="output.png") n
這個例子非常簡單而且經典,他做了下面的事情:
- 隨機初始化了一個由 5000 個節點組成的 price_network 模型
- 用 PropertyMap deg 保存所有節點的入度,用於保存節點的權重
- 對 deg 的值做了個簡單的函數變換
- 用 PropertyMap ebet 保存所有邊的 betweenness 中心度,用於保存邊的權重
- 將 ebet 的值歸一化到 0-10 之間
- 用 PropertyMap eorder 對 ebet 進行拷貝並取反,用於保存繪圖順序
- 用 PropertyMap pos 保存 sfdp 演算法生成的圖的坐標信息
- 將節點的大小、顏色用 deg 控制,將邊的粗細、顏色用ebet控制,隨後輸出成 png。
其他布局演算法與繪圖演算法
graphtool 提供了至少7種布局演算法,非常豐富。同時他也提供了社區分塊演算法與層級繪圖演算法,這裡就不細說了。
最後鏈一個簡單實驗:Weibo_Data_Analysis
(https://github.com/mythsman/Weibo_Data_Analysis/blob/master/README.md)
參考資料
graph-tool installation(https://git.skewed.de/count0/graph-tool/wikis/installation-instructions)
graph-tool(https://graph-tool.skewed.de/)
Github地址:http://t.cn/R8tnFki
轉載|出處:http://t.cn/RSmCTwc
小月兒
推薦閱讀:
※【Multiprocessing系列】Multiprocessing基礎
※一鍵開啟你的專屬博客!
※Python Generator漫談
※有哪些有趣的反爬蟲手段?
※使用 Python 連接 Todoist 與 Pomotodo
TAG:Python |