數據可視化(三)基於 Graphviz 實現程序化繪圖 頂 原 薦

前言

我之前在幾篇文章新一代Ntopng網絡流量監控—可視化和架構分析數據可視化(一)思維利器 OmniGraffle 繪圖指南 |201601,都曾提到了力導圖,在關於 OmniGraffle 的文章結尾還吐槽了一番自動佈局按鈕的坑。在本文中我力求將這個坑填上。

OmniGraffle 生成自動佈局圖形的基礎是 Graphviz 引擎。Graphviz(Graph Visualization Software)是一個由AT&T實驗室啓動的開源工具包,能夠支持基於 DOT 腳本,文件擴展名通常是 .gv 或 .dot 的描述繪製圖形。DOT 是一種文本圖形描述語言,將生成的圖形轉換成多種輸出格式的命令行工具,其輸出格式包括PostScript,PDF,SVG,PNG,含註解的文本等。DOT 本身非常原始,提供了一種非常簡單的描述圖形的方法,同時意味着可以在命令行終端使用,或者被其它編程語言調用(Graphviz 就可以作爲一個庫使用)。這一點非常關鍵,基於 Graphviz 應用開發者不必掌握佈局的複雜算法,而是可以把精力放在業務方面,將最後的圖對象交給繪圖引擎來處理即可。

有趣的是 Graphviz(Mac 版) 和 OmniGraffle 都曾獲得蘋果設計獎 Apple Design Awards

在深入掌握 Graphviz 及其相關衍生應用之前,我們有必要了解一些基礎理論 —— 圖論(Graph theory)。

一、背景知識:圖論(Graph theory)

  • 柯尼斯堡七橋問題

東普魯士柯尼斯堡(今日俄羅斯加里寧格勒)市區跨普列戈利亞河兩岸,河中心有兩個小島。小島與河的兩岸有七條橋連接。在所有橋都只能走一遍的前提下,如何才能把這個地方所有的橋都走遍?

許多數學家都嘗試去尋找這類問題的解決方案,後來發展成爲了數學中的圖論。圖論史上第一篇重要文獻是萊昂哈德·歐拉在1736年發表在聖彼得堡科學院的《柯尼斯堡的七橋》。該論文證明了柯尼斯堡七橋問題中,符合條件的走法並不存在,同時提出和解決了一筆畫問題。過橋問題可以抽象簡化爲平面上的點與線組合,每一座橋視爲一條線,橋所連接的地區視爲點。從這個點出發的線有奇數條稱爲奇點,從這個點出發的線有偶數條稱爲偶點。任意一種河──橋圖能否全部走一次的判定法則: 如果存在兩個以上(不包括兩個)奇頂點,路線不存在;且有n個奇頂點的圖至少需要n/2筆畫出。

1、經典適用場景

  • 路徑問題(柯尼斯堡七橋問題),最小生成樹問題,斯坦納樹
  • 網絡流與匹配問題:最大流問題,最小割問題,最大流最小割定理,最小費用最大流問題,二分圖及任意圖上的最大匹配,帶權二分圖的最大權匹配
  • 覆蓋問題:最大團、最大獨立集、最小覆蓋集、最小支配集

2、經典算法

  • 戴克斯特拉算法(D.A)
  • 克魯斯卡爾算法(K.A)
  • 普里姆算法(P.A)
  • 拓撲排序算法(TSA)
  • 關鍵路徑算法(CPA)
  • 廣度優先搜索算法(BFS)
  • 深度優先搜索算法(DFS)

二、Graphviz 簡明指南

1、Graphviz 佈局器

總的來說,Graphviz 支持兩類圖:無向圖(graph,用“ - - ”表示節點之間)和 有向圖(digraph,用“ ->” 表示節點之間)。頂點和邊都具有各自的屬性,比如形狀,顏色,填充模式,字體,樣式等。主要的佈局器如下:

  • dot: 默認佈局方式,主要用於有向圖;
  • neato:基於 sprint model 模型,又稱force-based 或者 energy minimized;
  • twopi:徑向佈局,放射狀;
  • circo:圓環佈局;
  • fdp:無向圖;
  • dotty:一個用於可視化與修改圖形的圖形用戶界面程序;
  • lefty:一個可以顯示 DOT 圖形的可編程控件,並允許用戶用鼠標在圖上執行操作。

2、Hello World!

$ brew install graphviz
$ dot -Tpng demo.dot -o demo.png
digraph demo{
  label="兒茶酚胺合成代謝路徑";

  酪氨酸 -> L多巴 -> 多巴胺 -> 去甲腎上腺素 -> 腎上腺素;

  下丘腦 -> 多巴胺;
  交感神經元 -> 去甲腎上腺素;
  腎上腺髓質 -> 去甲腎上腺素,腎上腺素;

  酪氨酸 [label="酪氨酸",color=green];
  多巴胺 [label="多巴胺", color=red];
  腎上腺素 [label="腎上腺素", color=red];

  下丘腦 [shape=box];
  交感神經元 [shape=box];
  腎上腺髓質 [shape=box];
}

兒茶酚胺合成代謝路徑-dot 佈局

3、twopi 徑向佈局

## 缺省爲 dot 佈局
$ dot -Kcirco -Tpng demo.dot -o demo.png

兒茶酚胺合成代謝路徑-twopi 徑向佈局

三、應用場景

1、軟件工程領域

軟件工程領域的複雜系統數據結構分析和軟件包依賴關係管理。例如 Linux 內核內部結構非常複雜,從概念上就由五個主要的子系統構成:進程調度器模塊、內存管理模塊、虛擬文件系統、網絡接口模塊和進程間通信模塊。這些模塊之間通過函數調用和共享數據結構進行數據交互,在涉及內核版本、應用程序升級等場景中,弄清楚模塊之間的依賴關係非常重要。

lsmod 命令用於顯示已經加載到內核中的模塊的狀態信息,Used by表示依賴的內容。通過 lsmod 命令獲取依賴信息之後,簡單處理就可以轉化爲圖形,而且圖形生成的全過程可以由程序固化。

$ lsmod
Module          Used by
vboxdrv         vboxnetadp,vboxnetflt,vboxpci
nf_reject_ipv4  ipt_REJECT
ebtables        ebtable_filter
ip6_tables      ip6table_filter
ip6_udp_tunnel  vxlan
udp_tunnel      vxlan
xor             btrfs
raid6_pq        btrfs
nf_nat_masquerade_ipv4       ipt_MASQUERADE
xfrm_algo        xfrm_user
nf_defrag_ipv4        nf_conntrack_ipv4

......

digraph kernel{
        vboxdrv->vboxnetadp,vboxnetflt,vboxpci;
        nf_reject_ipv4->ipt_REJECT;
        ebtables->ebtable_filter;
        ip6_tables->ip6table_filter;
        ip6_udp_tunnel->vxlan;
        udp_tunnel->vxlan;
        xor->btrfs;
        raid6_pq->btrfs;
        nf_nat_masquerade_ipv4->ipt_MASQUERADE;
        xfrm_algo->xfrm_user;
        nf_defrag_ipv4->nf_conntrack_ipv4;

        ......
}

軟件包依賴案例-Linux Kernel 1

軟件包依賴案例-Linux Kernel 2

軟件包依賴案例-Linux Kernel 3

基於 Graphviz 的一個開源項目 PlantUML 支持快速繪製各類 UML 圖形:時序圖、用例圖、類圖、活動圖、組件圖、狀態圖、對象圖等。

@startuml
scale 600 width

[*] -> State1
State1 --> State2 : Succeeded
State1 --> [*] : Aborted
State2 --> State3 : Succeeded
State2 --> [*] : Aborted
state State3 {
  state "Accumulate Enough Data\nLong State Name" as long1
  long1 : Just a test
  [*] --> long1
  long1 --> long1 : New Data
  long1 --> ProcessData : Enough Data
}
State3 --> State3 : Failed
State3 --> [*] : Succeeded / Save Result
State3 --> [*] : Aborted

@enduml

2、通信工程領域

  • nwdiag 是一個基於 Python 的、支持 Dot 腳本生成網絡圖的庫
  • 結合 GIS 信息追蹤網絡路由

網絡拓撲圖

pip install nwdiag
nwdiag simple.diag
nwdiag -Tsvg simple.diag
nwdiag {
  network dmz {
      address = "210.x.x.x/24"

      web01 [address = "210.x.x.1"];
      web02 [address = "210.x.x.2"];
  }
  network internal {
      address = "172.x.x.x/24";

      web01 [address = "172.x.x.1"];
      web02 [address = "172.x.x.2"];
      db01;
      db02;
  }
}

traceroute 案例

[root@li1437-101 ~]# traceroute www.google.com
traceroute to www.google.com (216.58.216.36), 30 hops max, 60 byte packets
 1  23.92.24.2 (23.92.24.2)  0.704 ms  0.736 ms 23.92.24.3 (23.92.24.3)  0.575 ms
 2  173.230.159.16 (173.230.159.16)  0.910 ms 173.230.159.14 (173.230.159.14)  2.265 ms
 		173.230.159.0 (173.230.159.0)  0.731 ms
 3  as15169.sfmix.org (206.197.187.50)  4.039 ms eqixsj-google-gige.google.com (206.223.116.21)  0.718 ms
 		as15169.sfmix.org (206.197.187.50)  3.944 ms
 4  108.170.242.227 (108.170.242.227)  4.902 ms
 		108.170.242.226 (108.170.242.226)  3.003 ms
 		108.170.243.2 (108.170.243.2)  3.064 ms
 5  216.239.47.37 (216.239.47.37)  4.836 ms 64.233.174.91 (64.233.174.91)  1.476 ms  1.447 ms
 6  216.239.54.22 (216.239.54.22)  12.464 ms  29.292 ms 64.233.174.204 (64.233.174.204)  9.032 ms
 7  209.85.245.172 (209.85.245.172)  10.633 ms
    108.170.230.130 (108.170.230.130)  20.010 ms
 		108.170.230.124 (108.170.230.124)  8.988 ms
10  lax02s22-in-f4.1e100.net (216.58.216.36)  10.358 ms  10.383 ms  10.301 ms
digraph {
    label="Google Trace Sample";
    "23.92.24.2" [label="23.92.24.2 \n Fremont,California \n location:37.5670,-121.9829"] ;
    as15169 [label="as15169.sfmix.org \n San Francisco \n Metropolitan Internet Exchange"];
    "108.170.242.227" [label="108.170.242.227 \n California \n location:37.4192,-122.0574"];
    lax02s22 [label="ax02s22-in-f4.1e100.net \n Los_Angeles,California \n location:46.07305,-100.546"];
    "23.92.24.2" -> as15169 -> "108.170.242.227"  -> lax02s22;
}

3、社會工程領域

  • 決策樹(Decision Tree):人羣鄙視鏈
  • 複雜人物關係鏈分析(《紅樓夢》、《權力的遊戲》)

鄙視鏈案例-婚姻市場中的房市-dot

鄙視鏈案例-婚姻市場中的房市-circo-圓環佈局

注意: 如果需要使用分組(Group)特性,子圖的名稱必須以“cluster”開頭,否則無法識別

digraph family {
  label ="《紅樓夢》人物關係譜·主要角色";

  subgraph cluster_皇族{
      label ="皇族";
      bgcolor="mintcream";
      node [ color="lightyellow", style="filled"];

      北靜王 [label = "北靜王",shape="Mrecord"];
      義忠順王 [label = "義忠順王",shape="Mrecord"];

      賈元春 [label = "賈元春(長女)\n 鳳藻宮尚書·賢德妃",shape="Mrecord"];
  }

  subgraph cluster_寧國公{
      label ="寧國公(西府)";
      bgcolor="mintcream";
      node [ color="green", style="filled"];

      賈演 [label = "賈演 \n 寧國公"];

      賈代化[label = "賈代化 \n 爵位:一等神威將軍 \n 職務(武官):京營節度使",shape="Mrecord"];
      賈演 -> 賈代化[label = "子"];
      ......
    }
    ......
}

《紅樓夢》人物關係譜·主要角色

擴展閱讀:數據可視化

更多精彩內容掃碼關注公衆號:RiboseYim's Blog:http://riboseyim.github.io/2017/09/15/Visualization-Graphviz/

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