最近找到 Graphviz 這個 graph drawing tool. 太好用了。
今天才搞懂為什麼有的論文可以畫很複雜的圖了,我還以為要用 Latex 之類來畫哩
◎ Graphviz 的特點就是只要提供 nodes 之間的關係,它就用其 layout 的演算法,將美美的圖畫出來,比如只要寫下面的 Code..
digraph gr {
a -> b;
a -> c;
d -> e;
d -> f;
}
就幫你畫出下述的圖
◎ 當然,就一般簡單的需求,這樣似乎就夠用了,但事實上仍有需要微調的情形,比如上述的圖,加上一個條件,比如
c->f
會畫出這樣的圖
這樣看起來也蠻合理,但我的需求是要 a, d 兩點對齊,那加 rank=same 的條件,來達到目的,code 如下:
digraph gr {
a -> b;
a -> c;
d -> e;
d -> f;
c -> f;
{rank=same; a; d;}
{rank=same; b; c;}
{rank=same; b; f;}
}
分別 (a,d) (b,c) (b,f) 兩兩對齊,現在就可以產生下述的圖:
◎ 上面還是有個問題,e, f 兩個節點,順序我並不想換啊...
它錯了嗎?也沒有,因為它的邏輯在於算最小的 edge 距離和最小排序,這樣是最佳解是沒錯的。
另外,有 ordering=out 的 option 可以用,這個選項是指, node 的 output nodes 由左至右排序。
但我加了這個項目後,畫出來的圖也沒變,d node 的兩個 childs 順序也沒變。它錯了嗎?它也沒錯,我猜因為 a->c->f 這條路早於 d->f 這條路先算,所以,f 還是要排左邊。
有解嗎? 有的.. 如下
- ordering=out 要加
- 為 e, f 增加一個 pseudo parent,並將 e,f 順序列為該 node 的 childs.
即增加 ordering=out 的權重,如下圖的 pseudo parent z
這樣 e,f 兩個 nodes 順序就交換過來了,然後,將 z 隱藏起來,並提高 z 的 rank 就成了。
最後的 Code 如下:
digraph gr {
ordering = out
a -> b;
a -> c;
d -> e;
d -> f;
c -> f;
{rank=same; a; d;}
{rank=same; b; c;}
{rank=same; b; f;}
z [style=invis];
z -> e [style=invis];
z -> f [style=invis];
{rank=source; z;}
}
◎ 這種只給關係式,然後畫出「可接受」的圖,背後的理論應該蠻有趣,也蠻不容易的。
Orignal From: Graphviz 筆記