Graphviz 適合編程快速繪制流程圖之類的圖形,。 而pygraphviz對graphviz進(jìn)行了封裝,,提供python程序調(diào)用接口,。網(wǎng)上有很多對graphiviz進(jìn)行python封裝的程序如pydot等等,,個(gè)人覺得pygraphviz比較好用,,有好的文檔和示例程序,。https://networkx./trac/browser/pygraphviz/
在ubuntu下面安裝 graphviz sudo apt-get install graphviz, graphviz-dev 注意graphiviz-dev是pygraphviz所依賴的必須安裝,。 安裝pygraphviz 注意不要sudo apt-get了,因?yàn)檫@樣安裝的不是最新版本,,程序運(yùn)行會有問題,。 到這個(gè)地址下載最新的pygraphviz-0.99.1.tar.gz (md5) 解壓縮,然后 sudo python2.6 setup.py install即可,。
下面給個(gè)例子,,如何利用graphiviz 的布局繪制下面的圖形呢:
1 //s.dot
2 //dot s.dot -Tpng -o s.png -Gsplines=line 3 digraph G { 4 //a -> c; 5 a -> b; 6 b -> c; 7 subgraph x{ 8 rank=same; 9 b->d; 10 } 11 subgraph y{ 12 //rank = same; 13 d->e; 14 } 15 subgraph z{ 16 rank=same; 17 c->e; 18 } 19 20 } 21
這里解釋下,默認(rèn)的圖布局是自上到下的,,TD,,當(dāng)然你可以改成自左向右布局, digraph G { ..... } 但是一個(gè)時(shí)刻只能有一種布局方式,例如上圖是采用從上到下的布局方式,為了使得邊b->d能夠水平,需要采用 subgraph 的方法添加子圖,同時(shí)說明rank=same. dot s.dot -Tpng -o s.png -Gsplines=line 中-Gsplines=line 表示強(qiáng)迫邊是直線.
http://www./mywiki/FaqBalanceTree 1 digraph G {
2 a -> b0 3 xb [label="",width=.1,style=invis] 4 a -> xb [style=invis] 5 a -> b1 6 {rank=same b0 -> xb -> b1 [style=invis]} 7 b0 -> c0 8 xc [label="",width=.1,style=invis] 9 b0 -> xc [style=invis] 10 b0 -> c1 11 {rank=same c0 -> xc -> c1 [style=invis]} 12 }
下面給出利用pygrahviz進(jìn)行二叉樹的繪制 首先給出最簡單的繪制,然后是按照上面提到的利用invis屬性,,構(gòu)造不可見的頂點(diǎn)和邊強(qiáng)迫產(chǎn)生較合適的位置,。 a | b0—t--b1 原理如昨圖所示,對照上面的圖示a到b0,a到b1是實(shí)邊,t為不可見點(diǎn),,a到t,,b0到t,t到b1都是不可見邊, 這樣強(qiáng)迫布局的時(shí)候?qū)τ跈M坐標(biāo),,a盡量在b0,b1的中間,。
1.不采用不可見點(diǎn),邊的二叉樹繪制效果 1 #printTreeOld.py 2 import pygraphviz as pgv
3 4 A=pgv.AGraph(directed=True,strict=True) 5 A.add_edge(1,2) 6 A.add_edge(1,3) 7 A.add_edge(2,4) 8 A.add_edge(2,5) 9 A.add_edge(5,6) 10 A.add_edge(5,7) 11 A.add_edge(3,8) 12 A.add_edge(3,9) 13 A.add_edge(8,10) 14 A.add_edge(8,11) 15 A.graph_attr['epsilon']='0.001' 16 print A.string() # print dot file to standard output 17 A.write('fooOld.dot') 18 A.layout('dot') # layout with dot 19 A.draw('fooOld.png') # write to file
2.采用不可見點(diǎn),,邊,,繪制二叉樹的效果,感覺稍微好一點(diǎn),更像二叉樹了:) 下面的代碼僅僅是示例,可以提出子函數(shù)簡化代碼,。
1 import pygraphviz as pgv
2 # strict (no parallel edges) 3 # digraph 4 # with attribute rankdir set to 'LR' 5 A=pgv.AGraph(directed=True,strict=True) 6 A.add_edge(1,2) 7 A.add_edge(1,3) 8 A.add_node('a',style='invis') 9 A.add_edge(1,'a',style='invis') 10 B=A.add_subgraph([2,3,'a'],rank='same') 11 B.add_edge(2,'a',style='invis') 12 B.add_edge('a',3,style='invis') 13 14 A.add_edge(2,4) 15 A.add_edge(2,5) 16 A.add_node('b',style='invis') 17 A.add_edge(2,'b',style='invis') 18 C=A.add_subgraph([4,5,'b'],rank='same') 19 C.add_edge(4,'b',style='invis') 20 C.add_edge('b',5,style='invis') 21 22 A.add_edge(5,6) 23 A.add_edge(5,7) 24 A.add_node('c',style='invis') 25 A.add_edge(5,'c',style='invis') 26 D=A.add_subgraph([6,7,'c'],rank='same') 27 D.add_edge(6,'c',style='invis') 28 D.add_edge('c',7,style='invis') 29 30 A.add_edge(3,8) 31 A.add_edge(3,9) 32 A.add_node('d',style='invis') 33 A.add_edge(3,'d',style='invis') 34 E=A.add_subgraph([8,9,'d'],rank='same') 35 E.add_edge(8,'d',style='invis') 36 E.add_edge('d',9,style='invis') 37 38 A.add_edge(8,10) 39 A.add_edge(8,11) 40 A.add_node('e',style='invis') 41 A.add_edge(8,'e',style='invis') 42 F=A.add_subgraph([10,11,'e'],rank='same') 43 F.add_edge(10,'e',style='invis') 44 F.add_edge('e',11,style='invis') 45 46 47 A.graph_attr['epsilon']='0.001' 48 print A.string() # print dot file to standard output 49 A.write('foo.dot') 50 A.layout('dot') # layout with dot 51 A.draw('foo.png') # write to file 52 |
|