Graphviz 适合编程快速绘制流程图之类的图形。
而pygraphviz对graphviz进行了封装,提供python程序调用接口。网上有很多对graphiviz进行python封装的程序如pydot等等,个人觉得pygraphviz比较好用,有好的文档和示例程序。https://networkx.lanl.gov/trac/browser/pygraphviz/
在ubuntu下面安装 graphviz
sudo apt-get install graphviz, graphviz-dev
注意graphiviz-dev是pygraphviz所依赖的必须安装。
安装pygraphviz
注意不要sudo apt-get了,因为这样安装的不是最新版本,程序运行会有问题。
到这个地址下载最新的pygraphviz-0.99.1.tar.gz (md5)
http://pypi.python.org/pypi/pygraphviz/
解压缩,然后 sudo python2.6 setup.py install即可。
下面给个例子,如何利用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
这里解释下,默认的图布局是自上到下的,TD,当然你可以改成自左向右布局,
digraph G {
rankdir=LR;
.....
}
但是一个时刻只能有一种布局方式,例如上图是采用从上到下的布局方式,为了使得边b->d能够水平,需要采用
subgraph 的方法添加子图,同时说明rank=same.
dot s.dot -Tpng -o s.png -Gsplines=line 中-Gsplines=line 表示强迫边是直线.
http://www.graphviz.org/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进行二叉树的绘制
首先给出最简单的绘制,然后是按照上面提到的利用invis属性,构造不可见的顶点和边强迫产生较合适的位置。
a
|
b0—t--b1 原理如昨图所示,对照上面的图示a到b0,a到b1是实边,t为不可见点,a到t,b0到t,t到b1都是不可见边,
这样强迫布局的时候对于横坐标,a尽量在b0,b1的中间。
1.不采用不可见点,边的二叉树绘制效果
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.采用不可见点,边,绘制二叉树的效果,感觉稍微好一点,更像二叉树了:)
下面的代码仅仅是示例,可以提出子函数简化代码。
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
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。