使用Graphviz快速绘制流程图

字数 564阅读 2619

简介

自己在绘制流程图的时候一般用到的是Visio,但是感觉连线以及框图位置调整起来很烦…经过一番了解之后发现了Graphviz可以使用Python代码来绘制流程图的软件,使用这个工具我们可以更专注于关系之间的表示而不是绘制的方法。先来看看一个神经网络的效果图吧:(Ref:https://blog.csdn.net/ztguang/article/details/77451803):

下载安装

对于Python包来说直接一句pip install graphviz即可,参考
Graphviz Docs
来试一下:

from graphviz import Digraph
dot = Digraph(comment='The Round Table')
dot.node('A', 'King Arthur')
dot.node('B', 'Sir Bedevere the Wise')
dot.node('L', 'Sir Lancelot the Brave')
dot.edges(['AB', 'AL'])
dot.edge('B', 'L', constraint='false')
dot.view()

报错了?

ExecutableNotFound: failed to execute ['dot', '-Tpdf', '-O', 'Digraph.gv'], make sure the Graphviz executables are on your systems' PATH

意思就是没有加入系统路径,所以再从官网上下载dot这些命令的可执行文件
https://graphviz.gitlab.io/_pages/Download/Download_windows.html

Note: These Visual Studio packages do not alter the PATH variable or access the registry at all. If you wish to use the command-line interface to Graphviz or are using some other program that calls a Graphviz program, you will need to set the PATH variable yourself.

然后添加PATH路径


重新执行上面的代码,成功了,不过是用pdf阅读软件打开的,如果使用的是Anaconda,可以用Spyder或Jupyter notebook直接再打一个dot就可以显示

快速绘制

不要忘了我们用这个工具的原因是Visio用起来比较麻烦,所以如果这个工具画的速度比较慢就失去了用它的意义。

  • 对于只用一次的节点可以直接用label来描述,需要重用的则使用缩略id
from graphviz import Digraph
dot=Digraph()
#因为Graph这个节点在后面和别的点连接的比较多,所以简写为g
#下面这句话实际是dot.node("g",label="Graph")
dot.node("g","Graph")
#不用简写的直接采用label来表示
dot.edge("Session","g")
dot.edge("g","Placeholder")
dot.edge("g","Variable")
dot
from graphviz import Source
code2="""graph
graphname{
rankdir=LR;  //Rank Direction Left to Right
a[label="node1"];
a -- node2;
}"""
t=Source(code2)
t

例子

下面我们来大致(是真的很大致…)还原一下这个


from graphviz import Graph
#排列方式设定为环形
g=Graph(engine="circo")
#节点1为白色
g.node("1",shape="circle",color="white")
for i in range(2,8):
    #第二层节点为红色
    g.node("%d"%i,shape="circle",color="red")
    #第三层为默认颜色
    a=2*(i-2)+8
    b=2*(i-2)+9    
    g.node("%d"%a,shape="circle") 
    g.node("%d"%b,shape="circle") 
    #添加第二层到第三层的边
    g.edge("1","%d"%i)
    #添加第三层到第二层的边
    g.edge("%d"%a,"%d"%i)
    g.edge("%d"%b,"%d"%i)
#添加
g.node("last",shape="box")
g.node("tail",shape="box") 
g.edge("last","7")
g.edge("tail","17")
g

虽然可以通过方向控制符(n,ne,e,se,s,sw,w,nw)指定一条边从起点的哪个位置射出和从哪个位置结束,但是这对上图来说还是太麻烦了…看样子,这种需要关注于绘制方式的图,它还不太适合呢。

推荐阅读更多精彩内容