Graphviz -图形可视化,python实现

时间:2023-02-03 12:21:21

系统

自己的系统是 Mac OSX EI Capitan
python版本是 python3.5 64bit

在Graphviz 官网查看到的mac os 的版本比较旧,没找到当前系统的版本。据其介绍http://www.graphviz.org/Download_macos.php
Graphviz -图形可视化,python实现
最后选择最简单直接的方法,使用brew安装
安装brew的方法 http://brew.sh/,终端中执行以下命令。

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

安装 Graphviz:

brew install graphviz

python安装graphviz方法:
在终端中使用命令

pip3 install graphviz

前提是已经安装了pip3,一般装完python3会自动安装的。

解读

根据官网上提供的例子。

from graphviz import Digraph

dot = Digraph(comment='The Round Table')

#添加圆点 A, A的标签是 King Arthur
dot.node('A', 'King Arthur')
dot.view() #后面这句就注释了,也可以使用这个命令查看效果

#添加圆点 B, B的标签是 Sir Bedevere the Wise
dot.node('B', 'Sir Bedevere the Wise')
#dot.view()

#添加圆点 L, L的标签是 Sir Lancelot the Brave
dot.node('L', 'Sir Lancelot the Brave')
#dot.view()

#创建一堆边,即连接AB的边,连接AL的边。
dot.edges(['AB', 'AL'])
#dot.view()

#在创建两圆点之间创建一条边
dot.edge('B', 'L', constraint='false')
#dot.view()

#获取DOT source源码的字符串形式
print(dot.source)
# doctest: +NORMALIZE_WHITESPACE
#The Round Table
#digraph {
# A [label="King Arthur"]
# B [label="Sir Bedevere the Wise"]
# L [label="Sir Lancelot the Brave"]
# A -> B
# A -> L
# B -> L [constraint=false]
#}

#保存source到文件,并提供Graphviz引擎
dot.render('test-output/round-table.gv', view=True)

输出的图
Graphviz -图形可视化,python实现

解读:
以上的程序一次完成输出,可以直接输出图形,有一个直接的感受。
但是,通过查看源码,可以发现共有五个文件:
_compat.py , dot.py, files.py, lang.py,tools.py

其中以上程序中用到的基本都在dot.py中,查看文件。
文件*定义了三个类:Dot,Graph,Digraph,后两者都是继承Dot.

以上使用的dot实例对象具有 Dot的所有属性与方法。因此以上使用的方法的语法可以参考 Dot的类定义。

同时在类Dot 继承自files.py中的File类,因此上面使用的dot.render的语法可以在File类中查看。

并且可以发现File类有个 view 方法,顾名思义,可以展示图片。
也就是说,在上面的程序中,每次添加一个圆节点或者连接边时,都可以调用

dot.view()  

来即时的查看效果。

:另一种更便捷的查看语法的方法,是在python ide或者终端中进行查看:

import graphviz
help(graphviz)

所有属性都在一个页面中,这种查看更直接,不需要在多个文件中看。

拓展

在上面的例子中,使用

print(dot.source)
#or
dot.source

可以得到绘画此图的 dot语言。
那么,如果有dot语言以及对应的图怎么写出python程序?

进入Graghviz官网,找到图库gallery,
http://www.graphviz.org/Gallery.php

以第一个例子cluster来说明,其他类似:
Graphviz -图形可视化,python实现

从上面可以看出:
大图 graph G 包括两个子图 cluster_0, cluster_1, 以及两个节点 start, end

两个子图仅以cluster_0为例:
子图属性有:style,color,label,节点设置
子图包括四个个节点,无属性设置。

sub_g0 = Digraph(comment="process1",graph_attr={"style":'filled',"color":'lightgrey'},node_attr={"style":"filled","color":"white"})
sub_g0.node("a0","a0")
sub_g0.view()

start,end节点只有一个shape属性。

dot = Digraph()
dot.node("start",label="start",shape="Mdiamond")
dot.node("
end",label="end",shape="Mdiamond")

整个程序:

from graphviz import Digraph
grap_g = Digraph("G",format="pdf")


sub_g0 = Digraph(comment="process1",graph_attr={"style":'filled',"color":'lightgrey'},node_attr={"style":"filled","color":"red"})
sub_g0.node("a0","a0")
sub_g0.node("a1","a1")
sub_g0.node("a2","a2")
sub_g0.node("a3","a3")
sub_g0.edge("a0","a1")
sub_g0.edge("a1","a2")
sub_g0.edge("a2","a3")

subg0.edge("a3", "a0")

sub_g1 = Digraph(comment="process1",graph_attr={"style":'filled'})
sub_g1.node("B","b0")
sub_g1.node("C","b1")
sub_g1.node("D","b2")
sub_g1.node("E","b3")
sub_g1.edges(["BC","CD","DE"])

grap_g.node(
"start", label="start",shape="Mdiamond")
grap_g.node(
"end", label="end", shape="Mdiamond")

grap_g.subgraph(sub_g0)
grap_g.subgraph(sub_g1)
grap_g.edge("start","a0")
grap_g.edge("start","B")

grap_g.edge("a1","E")
grap_g.edge("D","a3")

grap_g.edge("a3","end")
grap_g.edge("E","end")

Graphviz -图形可视化,python实现
注:发现有的属性实现不了,后续如果更正了再来修改。

可以依照这个思路,在gallery中进行将其他的dot语言与图用python实现。