Graphviz 安装与使用示例

之前绘制各种流程图和示意图时,使用过微软的 Visio,也用过 PowerPoint、画图等程序。总觉得这些程序效率不高,其中的很多时间浪费在对格式的调整和修饰上。如果专注于定义图形的逻辑结构,而不参与具体实现过程,更有利于集中精力。这也是我一直追求纯文本编辑方案、偏爱命令行程序的主要原因。

Graphviz 就是这么一个命令行程序:它可以根据一种名为 dot 的图形结构描述语言,生成简洁美观的示意图。如结构图、流程图、UML 图等。本文包含对程序的安装和使用该程序绘制流程图的简介。

程序安装

作为一款开源软件,Graphviz 提供了可用于 Windows、macOS、Linux 等常见操作系统的程序包。这些程序包都可以在其官网下载页面找到。

Windows 操作系统

要在 Windows 操作系统中使用 Graphviz,下载对应的安装包后,双击运行,即可根据提示将其安装到计算机中。

但安装程序并未帮我们配置环境变量,因此还不能在任意目录下使用 Graphviz。你可以通过控制面板中的 “环境变量” 配置窗口,将 Graphviz 程序安装目录的 bin/ 文件夹添加到系统的 Path 变量中。

Linux 操作系统

对于 Ubuntu 等 Linux 发行版,Graphviz 已经被添加到官方的软件源中。因此可以通过下面的命令进行安装:

1
$ sudo apt-get install graphviz

对于 CentOS 等操作系统,Graphviz 已经被添加到其企业软件附加包(EPEL)中,可以在安装该附加包后,通过下面的命令安装:

1
$ sudo yum install graphviz

当然,你也可以从其官网下载对应的程序文件包进行安装。

程序简介

各子程序

如果你已经迫不及待地尝试过运行 graphviz 命令,一定会感到失望。因为系统提示没有这个程序。实际上,Graphviz 程序是由多个子程序组成的,它们适用于不同的构图需求。主要有:

  • dot:绘制有向图;
  • neato:绘制无向图;
  • twopi:绘制辐射状布局的图形;
  • circo:绘制圆环状布局的图形;
  • fdp:绘制无向图,使用了不同的算法;
  • sfdp:绘制大图幅的无向图;
  • patchwork:绘制树状图;
  • osage:绘制基于阵列的图形。

dot 语言简介

在介绍 Graphviz 程序的使用之前,需要先简单介绍 dot 语言。

dot 是 Graphviz 定义的一种图形结构描述语言,用于对图形的结构和样式进行定义。dot 首先将图形分为两类,即无向图(graph)和有向图(digraph);然后进一步将图形的组成元素分为三类:节点(node)、边(edge)和子图(subgraph)。图形的样式可以通过各部分的属性进行定义。使用 dot 语言描述一副图形的结构时,首先定义该图是无向图还是有向图,然后定义其包含的节点、边和子图,并分别定义各组成部分的属性。

流程图

该语言一个简单的流程图演示如下(感谢知乎轮子哥提供如此生动的例子):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
digraph coder {
// set graph attributes
resolution = 320

// set nodes' attributes
node [shape=rect] // set default shape
start, end [shape=Mrecord]
dead [shape=diamond, label="dead ?"]

// set edges' attributes
start -> work -> eat -> poop -> dead
dead -> burial [label=" Yes"]
dead -> work [label=" No", constraint=false]
burial -> end
}

在该示例中,digraph 定义该图形是一个有向图,之后的 coder 为图形的标识名,大括号内的部分包含图形结构的定义。resolution 项定义了该图的分辨率。之后的区块中,定义了各节点和它们的属性。其中 shape 属性为节点的轮廓形状,而 label 属性为节点内的文字标签。最后的区块定义了各节点之间的连接关系,即它们之间的边。该图中的边皆为有向边,它们使用 -> 表示。部分边还有文字标签等属性,用于对路径进行说明。

与有向图相对应的无向图使用 graph 关键字定义,其中的无向边用 -- 表示。此外,还可以使用 subgraph 定义子图等。想要详细了解 dot 语言,可以参考其官方文档

关系图

类似的,一个简单的社交网络图的 dot 语言代码如下所示,该图展现了初唐诗人的社交关系:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
digraph poets {
resolution = 320
node [fontname="FangSong"]
// poets network by https://github.com/MrQianJinSi/poetry_analyzer
王勃 -> 骆宾王 -> 李峤 -> 杜审言 -> 苏味道
骆宾王 -> 宋之问 -> 杜审言 -> 韦承庆
骆宾王 -> 沈佺期 -> 李贤
李峤 -> 骆宾王 -> 卢照邻
李峤 -> 宋之问
宋之问 -> 李世民 -> 魏征
宋之问 -> 沈佺期 -> 乔知之
宋之问 -> 陈子昂 -> 乔知之
沈佺期 -> 宋之问
沈佺期 -> 陈子昂
乔知之 -> 陈子昂
}

输入参数

Graphviz 各子程序的输入参数大同小异,其形式为:

1
$ command <input> <options>

这里的 command 代表具体的程序名;<input> 代表输入的内容,其输入即可以来自文件,也可以来自标准输入;而 <options> 为参数选项。主要的参数选项有:

  • -T <format>:指定输出文件的格式,如 FIG、PNG、PS 等;
  • -o <file>:指定输出文件;
  • -v:开启用于 Debug 的 Verbose 模式;
  • -V:显示程序版本号;
  • -?:显示程序帮助信息。

使用示例

下面渲染上文的演示代码作为程序的使用示例。将上文流程图的代码保存为 demo.gv,使用 cd 命令进入文件所在目录,然后执行:

1
$ dot demo.gv -T png -o demo.png

对于社交关系图,可将其保存为 poets.gv,然后执行:

1
$ fdp poets.gv -T png -o poets.png

运行该命令后,将得到输出的图片,它们分别是是一个简单的流程图和社交关系图。其中的社交关系图如下:

初唐诗人社交网络

如果你不确定该使用 Graphviz 中的哪个命令,那么你可以都试试,然后挑选出自己最满意的一个。此外,Graphviz 网站上还提供了更多的示例,方便使用者查看和学习。