https://mlln.cn/2018/09/25/python-graphviz%E5%9B%BE%E6%95%B0%E6%8D%AE%E5%8F%AF%E8%A7%86%E5%8C%96%E5%85%A5%E9%97%A8/
安装
graphviz为Graphviz图形绘制软件提供了一个简单的纯Python接口。它在Python 2.7和3.4+下运行。要使用pip安装它,请运行以下命令:
pip install graphviz
或者:
Anaconda下安装Graphviz推荐下面的方法:
在cmd终端运行:
conda install python-graphviz
基本用法
graphviz模块提供两个类:Graph和Digraph。他们使用DOT语言为无向和有向图创建图形描述。他们有相同的API。
通过实例化新的Graph或Digraph对象来创建图形:
from graphviz import Digraphdot = Digraph(comment='这是一个有向图')str(dot)
执行结果:
'// 这是一个有向图\ndigraph {\n}'
它们的构造函数允许设置图形的name,DOT代码的filename,源代码行的注释等。
使用node()和edge()或edges()方法将节点和边添加到图形对象:
- node()方法第一个参数是name, 第二个参数是label
- edges()方法可以一次添加多个边, 每个边用字符串表示, 比如AB表示从A到B的边
- edge()方法一次添加一个边
dot = Digraph(comment='这是一个有向图')dot.node('A', '作者')dot.node('B', '医生')dot.node('C', '律师')dot.edges(['AB', 'AC'])dot.edge('B', 'C')print(dot.source)
执行结果:
// 这是一个有向图digraph {A [label="作者"]B [label="医生"]C [label="律师"]A -> BA -> CB -> C}
使用render方法将保存dot源码, 并且会渲染图形, 使用view=True参数可以自动打开应用程序以便浏览生成的图:
# 将dot源码保存到文件:output-graph.gv# 同时会生成一个pdf文件: output-graph.gv.pdf view=True 可以调用本地程序显示dot.render('output-graph.gv', view=True)
除了PDF, 还可以生成其他格式, 比如png:
dot.format = 'png'dot.render('output-graph.gv', view=True)
由于这是jupyter notebook环境, 我们直接使用notebook展示生成的图片即可:
from IPython.display import display, ImageImage(dot.render('output-graph.gv'))
piped输出
为了直接获取Graphviz软件渲染结果, 而不是让它保存到文件中, 我们可以使用pipe()方法, 比如我们可以直接获取渲染后的svg源码:
from graphviz import Graphh = Graph('hello', format='svg')h.edge('Hello', 'World')print(h.pipe().decode('utf-8'))
jupyter notebook中显示
因为Graph和Bigraph类都有repr_svg()方法, 因此他们可以直接显示在notebook中, 而不需要做任何处理, 例如, 上面的svg图, 可以直接显示:
h
显示风格
使用graph_attr, node_attr, edge_attr参数, 你可以更改图中节点和边的显示样式:
ps = Digraph(name='pet-shop', node_attr={'shape': 'plaintext'})ps.node('parrot')ps.node('dead')ps.edge('parrot', 'dead')ps

创建完毕以后, 你可以更改这些样式:
ps.graph_attr['rankdir'] = 'LR'ps.edge_attr.update(arrowhead='vee', arrowsize='2')ps
属性
我们可以直接更改图中所有节点和边的属性, 相当于全局配置, 只要使用attr方法即可:
ni = Graph('ni')# 设置所有节点的形状ni.attr('node', shape='rarrow')ni.node('1', 'Ni!')ni.node('2', 'Ni!')# 如果单独设置, 优先级更高ni.node('3', 'Ni!', shape='egg')ni.node('4', 'Ni!')ni
使用引号和HTML作为label
在label中使用引号需要使用转义字符\:
ni.node('5', '\"Ni\"')ni

在label中使用html可以使用< >将html内容括起来, 比如, 我们可以使用下标sub:
ni.node('6', '<N<sub>i</sub>>')ni
子图和集群
Graph和Bigraph’对象都有subgraph()`方法用于添加子图, 它有两种用法:
- 可以直接添加一个Graph或者Bigraph对象: ```python p = Graph(name=’parent’) p.edge(‘spam’, ‘eggs’)
c = Graph(name=’child’, node_attr={‘shape’: ‘box’}) c.edge(‘foo’, ‘bar’)
p.subgraph(c) p
- 使用with代码块:```pythonp = Graph(name='parent')p.edge('spam', 'eggs')with p.subgraph(name='child', node_attr={'shape': 'box'}) as c:c.edge('foo', 'bar')p
引擎
渲染引擎可以选择多种, 而不仅仅是dot, 比如你可以使用neato:
g = Graph(engine='neato')
或者也可以直接更改渲染引擎:
g.engine = 'circo'
添加dot语句
有些应用场景是需要使用已经写好的dot语句的, 这时候我们可以直接调用body.append方法来追加dot语句:
rt = Digraph()rt.body.append('\t"King Arthur" -> {\n\t\t"Sir Bedevere", "Sir Lancelot"\n\t}')rt.edge('Sir Bedevere', 'Sir Lancelot', constraint='false')rt
使用dot文件和源码
我们可以直接使用Source类来直接实例化一个Source对象, 传入的参数就是dot源码, 然后可以调用render方法渲染成图片:
from graphviz import Sourcesrc = Source('digraph "the holy hand grenade" { rankdir=LR; 1 -> 2 -> 3 -> lob }')str(src)
执行结果
'<graphviz.files.Source object at 0x104200ad0>'
我们还可以直接使用from_file方法来从一个dot文件实例化:
src = Source.from_file('output-graph-font.gv')src
使用临时文件浏览图
很多时候我们要多次浏览绘制的图, 但是又不想保存这个文件, 那么我们可以使用临时文件保存生成的结果:
import tempfileg = Graph()g.node('spam')g.view(tempfile.mktemp('.gv'))
