分享

用graphviz,pygraphviz快速自动绘图

 dinghj 2020-04-08

Graphviz 适合编程快速绘制流程图之类的图形。

而pygraphviz对graphviz进行了封装,提供python程序调用接口。网上有很多对graphiviz进行python封装的程序如pydot等等,个人觉得pygraphviz比较好用,有好的文档和示例程序。https://networkx./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./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./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 
复制代码

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多