畫關係圖的小幫手 : graphviz

    最近因為想把一些東西視覺化,剛好想找東西來自動幫我畫圖,印象中在大神那邊看過。所以就找了 graphviz 來試用看看。
    graphviz 用的是一種叫做 dot 的語法,如果你需要的東西不會太複雜的話,基本上它做出來的結果都還不錯。不滿意的話,套件裡面也提供可以手動更改的程式,不過我在windows上總是會遇到錯誤訊息,而且出來的圖不太對,所以就放棄了。
    對於一張簡單的關係圖或是流程圖來說,差異只在於箭號的有無,一般來說,如果你的圖是流程圖,可能就是一堆箭頭指來指去,那就是 directed graph 有向圖,否則就是 undirected graph 無向圖。如果是有向圖,語法就是:
digraph G{…}
    無向圖:
graph G{…}
    有向圖用的解譯程式是 dot,無向圖則用 neato。
    編譯圖的方式如下:
dot -T[output_filetype] [-G[option_name]] -o [output_filename] [input_filename]
neato -T[output_filetype] [-G[option_name]] -o [output_filename] [input_filename]
    像下面的範例,因為比較簡單,都是用:
neato -Tpng -o output.png input.dot
    用 .dot 當作輸入的副檔名是因為這樣 vim 會自己辨識使用格式,這樣能讓你在編輯的時候一目了然。當然你可以用.txt或者任何你喜歡的名稱。
    那怎麼去標明點與點的關係呢?像這樣寫就好了:
“A” — “B”; /*表示無向圖的連結,用兩個”-”連接起來*/
“A” ->”C”; /*表示有向圖的連結*/
    讓我們寫一個範例:
graph G{
A — B; /* 不要引號也可以 */
C — A;
A — D — C;
}
    這就是我們的結果:
    如果點裡面的文字想要用中文怎麼辦?也可以,不過比較麻煩一點。
    你必須先把檔案轉成 UTF8 的格式,還記得介紹過的 vim 嗎?你可以用下面的指令轉:
:set enc=utf8
:set fileencoding=utf8
    然後多補其他的命令進去(包括指定字型及編碼等),我們把剛剛的範例修改如下:
graph G{
charset=big5; /*指定編碼用,這行可要可不要*/
node [fontname=”simhei.ttf”] /* 這行一定要用! */
A — B; /* 不要引號也可以 */
C — A;
A — D — C;
中文 — 台灣;
}
    結果如下:
    值得一提的是,通常在無向圖中會發生,就是node(點)可能會重疊,如果你不想要點重疊的話,就必須再指定這件事情,可以在 graph G{…}中,加入一行指令:
overlap=false;
    如果你發覺因為線條太多,把點遮住了,這是因為如果沒有指定的話,點之間的連接都是用直線,所以才會有這個現象,如果你允許讓他們可以轉折的話,就能盡量避免這個問題,同樣可以再加入一行指令:
splines=true;
    如果你嫌點或線太單調,也可以更動他們的初始設定,像這樣:
A — B [color=red];
    或甚至加上註解:
A — B [color=red, label=”comment”];
    或者你還想把線條加寬:
A — B [color=red, label=”comment”,style=bold];
    把結果輸出來就會像這樣:
    假如你對所有的線條都要作一樣的設定,其實不需要一個個加,可以在一開始的時候設定:
edge [color=red,style=bold];
    好啦,那這到底有什麼好處呢?記得那篇談藥物組合的《猜想與現實(二)》嗎?程式跑完的結果,經過篩選後大概有兩百多條線,五十多個點。靠人工視覺化當然可以做得到,但是既然有人已經做好自動畫圖的程式,何不使用看看?這就是做出來的成果(因為圖滿大張的,您有興趣再打開來看)。
    (像上面這個比較複雜的例子,輸入檔案裡面的指令都有包含 overlap=false, splines=true,另外在編譯的過程中,也用了 -Gmaxiter=99999999 來讓結果比較好看,並使用 -Gstart=rand 來隨機挑選起始點,跑了幾次選了一張我覺得比較適合的作為結果。)
    其他更詳細的訊息,你都可以在 graphviz 的網站上找到。
    使用補記:
    修改 edge 的寬度:
A — B [style=”setlinewidth(n)”] or edge[style=”setlinewidth(n)”]
    n是寬度,數值可以非整數。 bold 的預設值等同於 style=”setlinewidth(2)”。
    顏色支援 RGB, RGBA, HSV 的格式:
Colors can be specified using one of four formats.
“#%2x%2x%2x” Red-Green-Blue (RGB)
“#%2x%2x%2x%2x” Red-Green-Blue-Alpha (RGBA)
H[, ]+S[, ]+V Hue-Saturation-Value (HSV) 0.0 <= H,S,V <= 1.0
string color name
    雖然有 transparent color(透明色) 的支援,但就算用網站上面的範例也跑不出成功的結果,使用0415的snapshot雖然有透明色,但是顏色整個錯亂,可能這部份還有問題。以 RGBA 來說,可能的範例:
A — B[color=”#12345680″];
    最後的alpha 80 表示透明50%也就是若有兩顏色A,B重疊,則顏色會是 50%A + (1-50%)B。
    edge 的 weight 如果越高,表示這條線會越直,而且會越靠近連結的兩點,換言之,點的距離會比近。
    neato 可以使用 graph[model=subset],讓互相連接的點可以比較靠近。model 的另一個選擇是 circuit。
    neato edge的線條有 solid(實心細線), dashed(短線段), dotted(點), bold(粗)四種

你可能感兴趣的:(畫關係圖的小幫手 : graphviz)