用graphviz,pygraphviz快速自动绘图

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 的布局绘制下面的图形呢:

s


 

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  表示强迫边是直线.

 

 

a

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.不采用不可见点,边的二叉树绘制效果

fooOld

  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.采用不可见点,边,绘制二叉树的效果,感觉稍微好一点,更像二叉树了:)

foo

下面的代码仅仅是示例,可以提出子函数简化代码。

 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 

你可能感兴趣的:(Graph)