本系列介绍 文本转图片 工具支持的图形描述语言。图形描述语言将图片描述为代码或者文本,有利于版本管理,很适合嵌入 LaTeX 或 Markdown 文档。用于网站时,还可以减轻图片存储压力,因为图片可以根据代码在使用时生成。本文是该系列第六篇,介绍 Graphviz Dot 语言。
概述
Graphviz 是一款开源图形可视化软件。图可视化是将结构信息表示为抽象图和网络图的一种方法。它在网络、生物信息学、软件工程、数据库和网页设计、机器学习以及其他技术领域的视觉界面方面有重要的应用。
Graphviz 布局程序以简单的文本语言描述图形,并以有用的格式(如 web 页面的图像和 SVG)生成图形;PDF 或 Postscript,以供加入其他文件;或显示在交互式图形浏览器中。Graphviz 对于具体图有许多有用的特性,例如颜色、字体、表格节点布局、行样式、超链接和自定义形状的选项。
Graphviz 有 6 个引擎,分别是:
dot - “层次”或有向图的分层绘图。如果边具有方向性,这是默认使用的工具。 neato - “spring model” 布局。如果图不是太大(大约 100 个节点),而且您对它一无所知,那么这是默认的工具。Neato 试图最小化一个全局能量函数,它相当于统计多维尺度。 fdp - “spring model”的布局类似于neato,但它是通过减少力而不是利用能量来实现的。 sfdp - fdp 的多尺度版本,用于大图形的布局。 twopi - 径向布局,after Graham Wills 97。节点被放置在同心圆上,这取决于它们与给定根节点的距离。 circo - 圆形布局,after Six and Tollis 99, Kauffman and Wiese 02。这适用于多个循环结构的某些图,例如某些电信网络。
Graphviz 内容较多,本文仅简单介绍其语法,更多内容请参考 Graphviz 文档 。
语法
图形类型
无向图
使用关键词 graph
开始,连接线用 --
。
graph graphname {
a -- b -- c;
b -- d;
}
Graphviz 无向图
有向图
使用关键词 digraph
开始,连接线用 ->
。
digraph graphname {
a -> b -> c;
b -> d;
}
digraph graphname {
a -> b -> c;
b -> d;
} 有向图
属性
DOT语言中,可以对节点和边添加不同的属性。这些属性可以控制节点和边的显示样式,例如颜色,形状和线形。可以在语句和句尾的分号间放置一对方括号,并在其中中放置一个或多个属性-值对。多个属性可以被逗号和空格(, )分开。节点的属性被放置在只包含节点名称的表达式后。
graph graphname {
// label属性可以改变节点的显示名称
a [label="Foo"];
// 节点形状被改变了
b [shape=box];
// a-b边和b-c边有相同的属性
a -- b -- c [ color=blue];
b -- d [style=dotted];
}
graph graphname {
// label属性可以改变节点的显示名称
a [label="Foo"];
// 节点形状被改变了
b [shape=box];
// a-b边和b-c边有相同的属性
a -- b -- c [ color=blue];
b -- d [style=dotted];
} Graphviz设置属性
子图
需使用 subgraph
开始,并且子图名称以 cluster_
开头,如下:
digraph G {
subgraph cluster_0 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
a0 -> a1 -> a2 -> a3;
label = "process #1";
}
subgraph cluster_1 {
node [style=filled];
b0 -> b1 -> b2 -> b3;
label = "process #2";
color=blue
}
start -> a0;
start -> b0;
a1 -> b3;
b2 -> a3;
a3 -> a0;
a3 -> end;
b3 -> end;
start [shape=Mdiamond];
end [shape=Msquare];
}
digraph G {
subgraph cluster_0 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
a0 -> a1 -> a2 -> a3;
label = "process #1";
}
subgraph cluster_1 {
node [style=filled];
b0 -> b1 -> b2 -> b3;
label = "process #2";
color=blue
}
start -> a0;
start -> b0;
a1 -> b3;
b2 -> a3;
a3 -> a0;
a3 -> end;
b3 -> end;
start [shape=Mdiamond];
end [shape=Msquare];
} Graphviz子图
节点和边
多边形节点
digraph G{
box [shape=box];
polygon [shape=polygon];
ellipse [shape=ellipse];
oval [shape=oval];
circle [shape=circle];
point [shape=point];
egg [shape=egg];
triangle [shape=triangle];
plaintext [shape=plaintext];
plain [shape=plain];
diamond [shape=diamond];
trapezium [shape=trapezium];
parallelogram [shape=parallelogram];
house [shape=house];
pentagon [shape=pentagon];
hexagon [shape=hexagon];
septagon [shape=septagon];
octagon [shape=octagon];
doublecircle [shape=doublecircle];
doubleoctagon [shape=doubleoctagon];
tripleoctagon [shape=tripleoctagon];
invtriangle [shape=invtriangle];
invtrapezium [shape=invtrapezium];
invhouse [shape=invhouse];
Mdiamond [shape=Mdiamond];
Msquare [shape=Msquare];
Mcircle [shape=Mcircle];
rect [shape=rect];
rectangle [shape=rectangle];
square [shape=square];
star [shape=star];
none [shape=none];
underline [shape=underline];
cylinder [shape=cylinder];
note [shape=note];
tab [shape=tab];
folder [shape=folder];
box3d [shape=box3d];
component [shape=component];
promoter [shape=promoter];
cds [shape=cds];
terminator [shape=terminator];
utr [shape=utr];
primersite [shape=primersite];
restrictionsite [shape=restrictionsite];
fivepoverhang [shape=fivepoverhang];
threepoverhang [shape=threepoverhang];
noverhang [shape=noverhang];
assembly [shape=assembly];
signature [shape=signature];
insulator [shape=insulator];
ribosite [shape=ribosite];
rnastab [shape=rnastab];
proteasesite [shape=proteasesite];
proteinstab [shape=proteinstab];
rpromoter [shape=rpromoter];
rarrow [shape=rarrow];
larrow [shape=larrow];
lpromoter [shape=lpromoter];
box->polygon->ellipse->oval->circle->point->egg;
triangle->plaintext->plain->diamond->trapezium->parallelogram->house;
pentagon->hexagon->septagon->octagon->doublecircle->doubleoctagon->tripleoctagon;
invtriangle->invtrapezium->invhouse->Mdiamond->Msquare->Mcircle->rect;
rectangle->square->star->none->underline->cylinder->note;
tab->folder->box3d->component->promoter->cds->terminator;
utr->primersite->restrictionsite->fivepoverhang->threepoverhang->noverhang->assembly;
signature->insulator->ribosite->rnastab->proteasesite->proteinstab;
rpromoter->rarrow->larrow->lpromoter;
}
digraph G{
box [shape=box];
polygon [shape=polygon];
ellipse [shape=ellipse];
oval [shape=oval];
circle [shape=circle];
point [shape=point];
egg [shape=egg];
triangle [shape=triangle];
plaintext [shape=plaintext];
plain [shape=plain];
diamond [shape=diamond];
trapezium [shape=trapezium];
parallelogram [shape=parallelogram];
house [shape=house];
pentagon [shape=pentagon];
hexagon [shape=hexagon];
septagon [shape=septagon];
octagon [shape=octagon];
doublecircle [shape=doublecircle];
doubleoctagon [shape=doubleoctagon];
tripleoctagon [shape=tripleoctagon];
invtriangle [shape=invtriangle];
invtrapezium [shape=invtrapezium];
invhouse [shape=invhouse];
Mdiamond [shape=Mdiamond];
Msquare [shape=Msquare];
Mcircle [shape=Mcircle];
rect [shape=rect];
rectangle [shape=rectangle];
square [shape=square];
star [shape=star];
none [shape=none];
underline [shape=underline];
cylinder [shape=cylinder];
note [shape=note];
tab [shape=tab];
folder [shape=folder];
box3d [shape=box3d];
component [shape=component];
promoter [shape=promoter];
cds [shape=cds];
terminator [shape=terminator];
utr [shape=utr];
primersite [shape=primersite];
restrictionsite [shape=restrictionsite];
fivepoverhang [shape=fivepoverhang];
threepoverhang [shape=threepoverhang];
noverhang [shape=noverhang];
assembly [shape=assembly];
signature [shape=signature];
insulator [shape=insulator];
ribosite [shape=ribosite];
rnastab [shape=rnastab];
proteasesite [shape=proteasesite];
proteinstab [shape=proteinstab];
rpromoter [shape=rpromoter];
rarrow [shape=rarrow];
larrow [shape=larrow];
lpromoter [shape=lpromoter];
box->polygon->ellipse->oval->circle->point->egg;
triangle->plaintext->plain->diamond->trapezium->parallelogram->house;
pentagon->hexagon->septagon->octagon->doublecircle->doubleoctagon->tripleoctagon;
invtriangle->invtrapezium->invhouse->Mdiamond->Msquare->Mcircle->rect;
rectangle->square->star->none->underline->cylinder->note;
tab->folder->box3d->component->promoter->cds->terminator;
utr->primersite->restrictionsite->fivepoverhang->threepoverhang->noverhang->assembly;
signature->insulator->ribosite->rnastab->proteasesite->proteinstab;
rpromoter->rarrow->larrow->lpromoter;
} Graphviz 多边形节点形状
Record-based 节点
digraph structs {
node [shape=record];
struct1 [label="<f0> left|<f1> mid\ dle|<f2> right"];
struct2 [label="<f0> one|<f1> two"];
struct3 [label="hello\nworld |{ b |{c|<here> d|e}| f}| g | h"];
struct1:f1 -> struct2:f0;
struct1:f2 -> struct3:here;
}
digraph structs {
node [shape=record];
struct1 [label="<f0> left|<f1> mid\ dle|<f2> right"];
struct2 [label="<f0> one|<f1> two"];
struct3 [label="hello\nworld |{ b |{c|<here> d|e}| f}| g | h"];
struct1:f1 -> struct2:f0;
struct1:f2 -> struct3:here;
} Record-based节点
节点风格
The style attribute can be used to modify the appearance of a node. At present, there are 8 style values recognized: filled, invisible, diagonals, rounded. dashed, dotted, solid and bold
. As usual, the value of the style attribute can be a comma-separated list of any of these. If the style contains conflicts (e.g, style="dotted, solid"
), the last attribute wins.
digraph G {
rankdir=LR
node [shape=box, color=blue]
node1 [style=filled]
node2 [style=filled, fillcolor=red]
node0 -> node1 -> node2
}
digraph G {
rankdir=LR
node [shape=box, color=blue]
node1 [style=filled]
node2 [style=filled, fillcolor=red]
node0 -> node1 -> node2
} style filled
digraph R {
rankdir=LR
node [style=rounded]
node1 [shape=box]
node2 [fillcolor=yellow, style="rounded,filled", shape=diamond]
node3 [shape=record, label="{ a | b | c }"]
node1 -> node2 -> node3
}
digraph R {
rankdir=LR
node [style=rounded]
node1 [shape=box]
node2 [fillcolor=yellow, style="rounded,filled", shape=diamond]
node3 [shape=record, label="{ a | b | c }"]
node1 -> node2 -> node3
} style rounded
箭头形状
箭头相关属性有 arrowhead
,arrowtail
,dir
,penwidth
等。以下是一个例子。
digraph G{
rankdir=TB;
a->b[arrowhead=box,dir=both,arrowtail=diamond,label="both"];
a->c[arrowhead=box,dir=forward,arrowtail=diamond,label="forward"];
a->d[arrowhead=box,dir=back,arrowtail=diamond,label="back"];
a->e[arrowhead=box,dir=none,arrowtail=diamond,label="none",penwidth=8];
}
digraph G{
rankdir=LR;
a->b[arrowhead=box,dir=both,arrowtail=diamond,label="both"];
a->c[arrowhead=box,dir=forward,arrowtail=diamond,label="forward"];
a->d[arrowhead=box,dir=back,arrowtail=diamond,label="back"];
a->e[arrowhead=box,dir=none,arrowtail=diamond,label="none",penwidth=8];
} WordPress Text2Chart
基本形状
基本形状有 11 个,分别是 box
,crow
,curve
,icurve
,diamond
,dot
,inv
,none
,normal
,tee
,vee
。示例代码如下:
digraph G{
rankdir=LR;
a->box [arrowhead=box];
a->crow [arrowhead=crow];
a->curve [arrowhead=curve];
a->icurve [arrowhead=icurve];
a->diamond [arrowhead=diamond];
a->dot [arrowhead=dot];
a->inv [arrowhead=inv];
a->none [arrowhead=none];
a->normal [arrowhead=normal];
a->tee [arrowhead=tee];
a->vee [arrowhead=vee];
}
digraph G{
rankdir=LR;
a->box [arrowhead=box];
a->crow [arrowhead=crow];
a->curve [arrowhead=curve];
a->icurve [arrowhead=icurve];
a->diamond [arrowhead=diamond];
a->dot [arrowhead=dot];
a->inv [arrowhead=inv];
a->none [arrowhead=none];
a->normal [arrowhead=normal];
a->tee [arrowhead=tee];
a->vee [arrowhead=vee];
} Graphviz 箭头形状
扩展形状
配合 修饰词(modifiers),还可以扩展出很多形状。有如下修饰词:
l - 裁剪形状,只留下边缘左边的部分。 r - 裁剪形状,只留下边缘右侧的部分。 o - 使用形状的开放(非填充)版本。
示例如下:
digraph G{
rankdir=LR;
a->box [arrowhead=box];
a->lbox [arrowhead=lbox];
a->rbox [arrowhead=rbox];
a->obox [arrowhead=obox];
a->olbox [arrowhead=olbox];
a->orbox [arrowhead=orbox];
}
digraph G{
rankdir=LR;
a->box [arrowhead=box];
a->lbox [arrowhead=lbox];
a->rbox [arrowhead=rbox];
a->obox [arrowhead=obox];
a->olbox [arrowhead=olbox];
a->orbox [arrowhead=orbox];
} 箭头修饰词
颜色
参见 官方文档 。
Graphviz画廊
digraph {
"A" [shape="circle"];
"B" [shape="rectangle"];
"C" [shape="diamond"];
"A" -> "B" [label="A to B"];
"B" -> "C" [label="B to C"];
"A" -> "C" [label="A to C"];
}
/* courtesy Ian Darwin and Geoff Collyer, Softquad Inc. */
digraph unix {
size="6,6";
node [color=lightblue2, style=filled];
"5th Edition" -> "6th Edition";
"5th Edition" -> "PWB 1.0";
"6th Edition" -> "LSX";
"6th Edition" -> "1 BSD";
"6th Edition" -> "Mini Unix";
"6th Edition" -> "Wollongong";
"6th Edition" -> "Interdata";
"Interdata" -> "Unix/TS 3.0";
"Interdata" -> "PWB 2.0";
"Interdata" -> "7th Edition";
"7th Edition" -> "8th Edition";
"7th Edition" -> "32V";
"7th Edition" -> "V7M";
"7th Edition" -> "Ultrix-11";
"7th Edition" -> "Xenix";
"7th Edition" -> "UniPlus+";
"V7M" -> "Ultrix-11";
"8th Edition" -> "9th Edition";
"1 BSD" -> "2 BSD";
"2 BSD" -> "2.8 BSD";
"2.8 BSD" -> "Ultrix-11";
"2.8 BSD" -> "2.9 BSD";
"32V" -> "3 BSD";
"3 BSD" -> "4 BSD";
"4 BSD" -> "4.1 BSD";
"4.1 BSD" -> "4.2 BSD";
"4.1 BSD" -> "2.8 BSD";
"4.1 BSD" -> "8th Edition";
"4.2 BSD" -> "4.3 BSD";
"4.2 BSD" -> "Ultrix-32";
"PWB 1.0" -> "PWB 1.2";
"PWB 1.0" -> "USG 1.0";
"PWB 1.2" -> "PWB 2.0";
"USG 1.0" -> "CB Unix 1";
"USG 1.0" -> "USG 2.0";
"CB Unix 1" -> "CB Unix 2";
"CB Unix 2" -> "CB Unix 3";
"CB Unix 3" -> "Unix/TS++";
"CB Unix 3" -> "PDP-11 Sys V";
"USG 2.0" -> "USG 3.0";
"USG 3.0" -> "Unix/TS 3.0";
"PWB 2.0" -> "Unix/TS 3.0";
"Unix/TS 1.0" -> "Unix/TS 3.0";
"Unix/TS 3.0" -> "TS 4.0";
"Unix/TS++" -> "TS 4.0";
"CB Unix 3" -> "TS 4.0";
"TS 4.0" -> "System V.0";
"System V.0" -> "System V.2";
"System V.2" -> "System V.3";
} UNIX
digraph finite_state_machine {
rankdir=LR;
size="8,5"
node [shape = doublecircle]; LR_0 LR_3 LR_4 LR_8;
node [shape = circle];
LR_0 -> LR_2 [ label = "SS(B)" ];
LR_0 -> LR_1 [ label = "SS(S)" ];
LR_1 -> LR_3 [ label = "S($end)" ];
LR_2 -> LR_6 [ label = "SS(b)" ];
LR_2 -> LR_5 [ label = "SS(a)" ];
LR_2 -> LR_4 [ label = "S(A)" ];
LR_5 -> LR_7 [ label = "S(b)" ];
LR_5 -> LR_5 [ label = "S(a)" ];
LR_6 -> LR_6 [ label = "S(b)" ];
LR_6 -> LR_5 [ label = "S(a)" ];
LR_7 -> LR_8 [ label = "S(b)" ];
LR_7 -> LR_5 [ label = "S(a)" ];
LR_8 -> LR_6 [ label = "S(b)" ];
LR_8 -> LR_5 [ label = "S(a)" ];
} 状态机
graph ER {
node [shape=box]; course; institute; student;
node [shape=ellipse]; {node [label="name"] name0; name1; name2;}
code; grade; number;
node [shape=diamond,style=filled,color=lightgrey]; "C-I"; "S-C"; "S-I";
name0 -- course;
code -- course;
course -- "C-I" [label="n",len=1.00];
"C-I" -- institute [label="1",len=1.00];
institute -- name1;
institute -- "S-I" [label="1",len=1.00];
"S-I" -- student [label="n",len=1.00];
student -- grade;
student -- name2;
student -- number;
student -- "S-C" [label="m",len=1.00];
"S-C" -- course [label="n",len=1.00];
label = "\n\nEntity Relation Diagram\ndrawn by NEATO";
fontsize=20;
} ER图
以上就是全部内容,欢迎到 文本转图片工具 试用。
发表回复