这一篇会介绍画图利器 Graphviz,并展示一些有侧重点的应用,并记录在完成毕设过程中探索 Graphviz 的过程。
Graphviz 是一个开源的图形可视化软件,官网: http://graphviz.org/
用户只需要使用 DOT 语言声明图中应该有哪些节点和边,Graphviz 就可以自动生成一个布局美观的输出(支持几十种输出,常见的图片格式都包括在内)。在官网的 Gallery 中有很多相当厉害的效果,如下:
这些都是自动生成出来的,是不是感觉 666 ?
但是有些同学看到还要先学 DOT 语言,就开始打退堂鼓了,实际上这个语言非常简单,几乎比 Markdown 都简单,看一两个例子就会写了 : ) 比如最简单的 Helloworld 例子:
digraph g {
hello->world
}
就可以得到下图:
再来个稍微复杂点的例子,绘制一个树状图,代码如下。在毕设中 Graphviz 就被我用来生成类似这样的图。
digraph g {
1->2 [label = "left"]
1->3 [label = "right"]
2->4
2->5
3->6
3->7
}
就可以得到下图:
实际上,Graphviz 能够提供的效果有很多很多种,无论是节点、边还是图,都有很多属性可以设置,在此就不一一列举了,官网的文档说得很清楚:http://graphviz.org/documentation/
当然了,虽然有这么多属性,但是常用的并不是很多。在毕设中,我经常用到的有以下几种属性:
- [style=invis] :让边或节点不可见,还有很多其他值可以设置
- [shape=point] : 设置节点的形状为一个点,还有很多其他值可以设置
- [shape=box, style=filled, height=0.3, width=0.3] :也可以这么用,同时设置形状、风格、高度和宽度
- [label="xxx"] :设置节点或边的标签(说明文字)为 xxx,就像上面的图一样
- [xlabel="xxx"] :另外一种形式的标签,和 label 属性相比,位置略有变化。且 xlabel 和 label 可以同时使用
- [tooltip="456
;123"] :(注意:左边属性的;应该写成英文状态下的 ; 符号才能有换行效果,平台似乎有屏蔽机制,当写成英文状态下的 ; 时就看不到了,只能写成中文状态下的分号,见谅)设置节点或边的 tooltip 属性,当导出的图像格式为 svg 时,使用浏览器打开图像,光标移动到设置该属性的节点或边上方,会看到说明文字,如下所示:
咳咳,写到这里发现还没说怎么安装和使用呢。。。赶快补上
以下步骤是对 Windows 系统的,Linux 下的使用请参考其他的文章。。。
1.打开下载页面https://graphviz.gitlab.io/_pages/Download/Download_windows.html 选择 .zip 文件下载并解压
2.有两种用法,一是用命令行,这个需要先添加环境变量,然后在命令行中敲命令。但是这个方法我不太熟,所以推荐另一个方法。打开 bin 目录,找到 gvedit.exe,这是一个编辑器,双击打开就可以写 DOT 语言描述的图,然后就可以设置输出格式、引擎之类的,最后生成结果。bin 目录中还有一个 GVedit.html 文件,是说明手册,可以参考。(可以看到 bin 目录还有很多可执行文件,里面有些工具很强大,还有待进一步的探索)
当写完 DOT 语言描述后,可以看到菜单栏有两个小人的图标,左边的是设置按钮,右边的是生成结果按钮,点击右边的按钮就可以立即看到 png 格式的输出图片。如果想要进一步设置的话,需要点击左边的按钮,如下图所示:
Layout Engine 布局引擎:
这一项指定的是绘图引擎,对于绘制不同类型的图像,需要选择不同的引擎,这样就可以得到不同的效果。虽然有很多选项,但是官网只重点介绍了下面六种:
- Dot:绘制“分层”或有向图的分层图。布局算法将边缘指向相同方向(从上到下或从左到右),然后尝试避免边缘交叉并减少边长。这个引擎是最常用的。
- Neato:这是一种“弹簧模型”的布局,当图中的点的数目不是很大时,将该布局会作为默认布局。它使用一种最小化全局能量函数,相当于统计多维缩放。这个引擎的输出看起来有点挤成一堆的感觉。
- Fdp:这是一种类似于neato的布局,是通过减少力而不是使用能量来实现的。当节点和边的数量有几十个甚至上百个时,这个引擎很好用。
- Sfdp:用于大图形布局的fdp的多尺度版本。但是经过我的实践,感觉在节点或边的数目较多时,fdp 比 sfdp 生成的效果更好。(而且要使用这个引擎,需要用命令行,似乎 gvedit.exe 没有提供这个引擎)
- Twopi:径向布局,节点根据它们与给定根节点的距离放置在同心圆上。其中根节点可以自行设置。
- Circo:适合绘制某些多循环结构的图表,例如某些电信网络。
至于其他的引擎,我没用过,感兴趣的同学可以试试看 : )
Output File Type 输出文件的格式:
这个就比较简单了,支持很多很多的格式输出,常用的格式有 jpg、png 和 svg 等等。
Output File Name 输出文件的名字:
这个也很简单,可以设置输出结果的名字和路径。
下面的其他选项我也不太清楚怎么使用,还在摸索中。。。如果有哪位大佬知道的话,欢迎在评论区交流 : )
最后,点击右下角的 OK,就可以生成输出结果了。
以上就是 Graphviz 的大致使用方式,当然还有很多更高级的用法和内容,由于个人精力原因,没有做进一步的探究。
不过,Graphviz 的官网给出了很多的资料,感兴趣的同学可以参考:
- 文档:http://graphviz.org/documentation/
- 论文、出版物等研究成果:http://graphviz.org/theory/
- 资源:http://graphviz.org/resources/
在资源页面,官网很贴心地搜集了一些很有用的工具,在毕设中,我使用了其中几个工具来实现绘图的自动化,详情敬请关注之后的博文~~~
最后,给出一些辛苦搜集并精心筛选后的 Graphviz 资料:
(其实仔细研读文档就能有很多的收获了)
-
http://graphviz.996277.n3.nabble.com/
国外的 Graphviz 论坛,一些疑难问题可以在里面搜索到解答。非常有帮助! -
类似Graphviz的工具是如何实现自动排版的? - 知乎
知乎里关于 Graphviz 原理的问答 -
http://graphs.grevian.org/
Graphviz 的口袋参考,里面有些简单的例子,还可以在线输入 DOT 得到 Graphviz 输出 -
graph - Graphviz Dot Algorithm - StackOverflow
StackOverflow 中关于 Graphviz 布局算法的讨论 -
https://dreampuf.github.io/GraphvizOnline/#
Graphviz 在线编译器,可以在线输入 DOT 得到 Graphviz 输出,我经常用来测试 -
Viz.js
另一个Graphviz 在线编译器,和上一个略有不同