graphviz基本使用及常见问题

一、认识graphviz

接触graphviz是几年前的一个项目,要画出数据网络的布局,使用graphviz能比较清楚的画出数据之间的关系。
可以在gallery中查看他能完成的图形:http://www.graphviz.org/gallery/。graphviz最方便的地方在于能够很快的清晰的画出点与点之间的关系,并且有许多布局算法能够很好的去布局。
之前使用它画过流程图,决策树。使用twopi画出数据的关联关系:

二、安装graphviz

官网下载:http://www.graphviz.org/download/。
根据自己的版本来选择:

 

安装在任意喜欢的位置。但是需要把安装目录的graphviz/bin加入环境变量PATH里,我这里只写了相对路径。
打开cmd,输入:dot --help,如果弹出以下信息,就是安装成功:

 

三、使用graphviz

3.1 基本信息

graphviz中包含了众多的布局器:

dot            默认布局方式,主要用于有向图
neato       基于spring-model(又称force-based)算法
twopi        径向布局
circo        圆环布局
fdp           用于无向图

以上布局我都使用过,但是个人比较倾向dot和twopi,可以根据需求来画图。

基本语法


字符串 都要加双引号, 可以加\n换行符
注释     双斜杠// 或/* */
有向图 digraph, 节点关系: 指向->
无向图 graph, 节点关系: 连通 --
属性 node[attribute1=value1, attribute2=value2]
大小: size=”2,2”; 单位为英寸
标签: label=”显示在图上的内容”
边:edge [color=red,style=dotted]; 这句话之后生效
节点:node [color=navy]; 这句话之后生效
边方向:rankdir=参数值;LR(从左到右),RL,BT,TB
节点形状: a[shape=box]; 默认是椭圆
边框大小:a[width=.1,height=2.5]; 单位为英寸
边框颜色:a[color=red];


构造边

关系    有向图   无向图
一对一    a->b;    a–b;
一对多    a->{b;c;d};   a–{b;c;d};
多对一    {b;c;d}->a;    {b;c;d}–a;
多对多    {m,n,p,q}->{b;c;d};    {m,n,p,q}->{b;c;d}


详细资料:
官方文档:http://www.graphviz.org/documentation/
属性设置:https://graphviz.gitlab.io/_pages/doc/info/attrs.html
节点形状:https://graphviz.gitlab.io/_pages/doc/info/shapes.html
箭头形状:https://graphviz.gitlab.io/_pages/doc/info/arrows.html
颜色配置:https://graphviz.gitlab.io/_pages/doc/info/colors.html

 

3.2 基本使用

以画一个dot布局为例子:
(1)建立一个first.dot脚本:

digraph first1{
    a;
    b;
    c;
    d;
    a->b;
    b->d;
    c->d;
}

解释:digraph是画图类型,接触高级使用可以有不同的类型,first2可以和文件名first不一样。画了abcd4个点。然后a->b表示a点指向b点,如果有线条的指向,可以不用先声明点。即,上述代码等价于:

digraph first2{
    a->b;
    b->d;
    c->d;
}

(2)画图
打开cmd到first.dot目录下,运行:
dot -Tpng first.dot -o first.png
可以得到画好的图形。
解释:dot表示使用的是dot布局,其他布局相应的修改即可,-T表示格式,即画成png格式,-o表示重命名为first.png。

在这里如果出现syntax error,可看第四部分常见问题解决。

(3)画图结果
上面的简单的代码得到以下结果:

一对多示例 

digraph demo1 {

    //解决中文乱码
    node[fontname = "Microsoft YaHei"];
    edge[fontname = "Microsoft YaHei"];
    graph[fontname = "Microsoft YaHei"];

    label="一对多示例"

    {你} -> {
        a;
        b;
        c;
    };

}

 关系

graph gvDemo1 {
    a -- b
    a -- b
    b -- a [color=blue]
}

有向图

digraph gvDemo2 {
    a -> b
    a -> b
    b -> a [color=blue style=filled]
}

多对多 

digraph gvABC {
    { a b c } -> { d e f }
}

 

digraph gvDemo {
    main -> parse -> execute;
    main -> init;
    main -> cleanup;
    execute -> make_string;
    execute -> printf
    init -> make_string;
    main -> printf;
    execute -> compare;
}
digraph gvDemo{
    node [peripheries=2 style=filled color="#eecc80"]
    edge [color="sienna" fontcolor="green"]
    main -> parse -> execute;
    main -> init [arrowhead = box];
    main -> cleanupi -> main;
    make_string[label = once shape=parallelogram style=filled ]
    execute -> make_string[label=Go style=dashed arrowtail=diamond];
    execute -> printf [shape=box];
    init -> make_string;
    main -> printf[dir=none];
    execute -> compare[dir=both];
}

 

digraph gvDemo3 {
    edge[fontname="Microsoft YaHei"]
    node[fontname="Microsoft YaHei"]
    graph[fontname="Microsoft YaHei"]
    label="游戏资源更新流程"
    rankdir="TB"
    start[label="启动游戏" shape=circle style=filled]
    ifwifi[label="网络环境判断是否 WIFI" shape=diamond]
    needupdate[label="是否有资源需要更新" shape=diamond]
    startslientdl[label="静默下载" shape=box]
    enterhall[label="进入游戏大厅" shape=box]


    enterroom[label="进入房间" shape=box]
    resourceuptodate[label="资源不完整" shape=diamond]
    startplay[label="正常游戏" shape=circle fillcolor=blue]
    warning[label="提醒玩家是否更新" shape=diamond]
    startdl[label="进入下载界面" shape=box]
    //{rank=same; needupdate, enterhall}


    {shape=diamond; ifwifi, needupdate}


    start -> ifwifi
    ifwifi->needupdate[label="是"]
    ifwifi->enterhall[label="否"]
    needupdate->startslientdl[label="是"]
    startslientdl->enterhall
    needupdate->enterhall[label="否"]


    enterhall -> enterroom
    enterroom -> resourceuptodate
    resourceuptodate -> warning[label="是"]
    resourceuptodate -> startplay[label="否"]
    warning -> startdl[label="确认下载"]
    warning -> enterhall[label="取消下载"]
    startdl -> enterhall[label="取消下载"]
    startdl -> startplay[label="下载完成"]
}

 

graph gvDemo4{
    "黑海" -- "亚速海";
    "黑海" -- "博斯普鲁斯海峡"
    "达达尼尔海峡" -- "爱琴海"
    subgraph cluster_T{//新东西
        label = "黑海海峡";//新东西
        "达达尼尔海峡" -- "马尔马拉海" -- "博斯普鲁斯海峡";
    }
    subgraph cluster_M{
        label = "地中海海域";
        "中部地中海" -- {"爱琴海" "爱奥尼亚海" "西西里海峡"}; //也是新东西
        "西部地中海" -- {"西西里海峡" "第勒尼安海" "利古里亚海" "伊比利海" "阿尔沃兰海"};
        "爱奥尼亚海" -- "亚得里亚海";
        "阿尔沃兰海" -- "直布罗陀海峡";
    }
} 
digraph G{
Country->Narrow;
Country->Middle;
Country->Large;
Narrow->small_underpopulated[label="small population"];
Narrow->small_overpopulated[label="large population"];顦
Large->vast_overpopulated[label="large population"]; 
Large->vast_underpopulated[label="small population"];
Middle->small_overpopulated[label="More than average"];顦
Middle->vast_underpopulated[label="Less than average"];
small_overpopulated->A[label="GDP:HIGH"];
small_overpopulated->B[label="GDP:LOW"];
vast_overpopulated->C[label="GDP:HIGH"];
vast_overpopulated->D[label="GDP:LOW"];
vast_underpopulated->E[label="GDP:HIGH"];
vast_underpopulated->F[label="GDP:LOW"];
F->F[label="NOT EXIST",color="red"];
small_underpopulated->G[label="GDP:HIGH"];
small_underpopulated->H[label="GDP:LOW"];
D->I[label="RoadScattered"];
D->Y[label="HighCoveraged"];
C->J[label="HighCoveraged"];
A->K[label="HighCoveraged"];
B->L[label="RoadScattered"];
G->M[label="HighCoveraged"];
H->H[label="Number Too Less",color="red"];
E->O[label="RoadScattered"];
E->P[label="HighCoveraged"];
M->Q[label="Both"];
K->R[label="Both"];
L->S[label="Oil More"];
O->T[label="Oil More"];
P->U[label="Both"];
J->V[label="Oil More"];
J->W[label="Both"];
K->X[label="Electricity More"];
I->Z[label="Neither"];
Y->1[label="Neither"];
Q->Q[color="red"];
R->R[color="red"];
X->X[color="red"];
S->S[color="red"];
T->T[color="red"];
U->U[color="red"];
V->V[color="red"];
W->W[color="red"];
Z->Z[color="red"];
1->1[label="Number Too Less",color="red"];
} 
 

 

digraph G {
    A -> B;
    A -> C -> B;
    A -> D -> B;
}

 节点形状

digraph G {
    size = "4, 4";
    main [shape=box]; /* 这是注释 */
    main -> parse [weight=8];
    parse -> execute;
    main -> init [style=dotted];
    main -> cleanup;
    execute -> { make_string; printf}
    init -> make_string;
    edge [color=red]; // 设置生效
    main -> printf [style=bold,label="100 times"];
    make_string [label="make a\n字符串"];
    node [shape=box,style=filled,color=".7 .3 1.0"];
    execute -> compare;
}

 标签

digraph G {
    a -> b -> c;
    b -> d;
    a [shape=polygon,sides=5,peripheries=3,color=lightblue,style=filled];
    c [shape=polygon,sides=4,skew=.4,label="hello world"]
    d [shape=invtriangle];
    e [shape=polygon,sides=4,distortion=.7];
}

 类似HTML的样式

 digraph html {
    abc [shape=none, margin=0, label=<
    <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4">
        <TR>
            <TD ROWSPAN="3"><FONT COLOR="red">hello</FONT><BR/>world</TD>
            <TD COLSPAN="3">b</TD>
            <TD ROWSPAN="3" BGCOLOR="lightgrey">g</TD>
            <TD ROWSPAN="3">h</TD>
        </TR>
        <TR>
            <TD>c</TD>
            <TD PORT="here">d</TD>
            <TD>e</TD>
        </TR>
        <TR>
            <TD COLSPAN="3">f</TD>
        </TR>
    </TABLE>>];
}

二分查找树 

digraph g {
    node [shape = record,height=.1];
    node0[label = "<f0> |<f1> G|<f2> "];
    node1[label = "<f0> |<f1> E|<f2> "];
    node2[label = "<f0> |<f1> B|<f2> "];
    node3[label = "<f0> |<f1> F|<f2> "];
    node4[label = "<f0> |<f1> R|<f2> "];
    node5[label = "<f0> |<f1> H|<f2> "];
    node6[label = "<f0> |<f1> Y|<f2> "];
    node7[label = "<f0> |<f1> A|<f2> "];
    node8[label = "<f0> |<f1> C|<f2> "];
    "node0":f2 -> "node4":f1;
    "node0":f0 -> "node1":f1;
    "node1":f0 -> "node2":f1;
    "node1":f2 -> "node3":f1;
    "node2":f2 -> "node8":f1;
    "node2":f0 -> "node7":f1;
    "node4":f2 -> "node6":f1;
    "node4":f0 -> "node5":f1;
}

 示例

 


//定义节点属性
digraph g {
    //==========定义节点关系============
    a->b;
    b->c;
    c->a;
    c->d->e->f;
    d->g;
    e->h;
    //==========定义节点属性============
    //定义a节点为长方形, 样式为填充, 填充颜色为#ABACBA
    a[shape=box,label="Server1\nWebServer",fillcolor="#ABACBA",style=filled];
    //定义b为5边形, 标签为"bb", 样式为填充, 填充色为red
    b[shape=polygon,sides=5,label="bb",style=filled,fillcolor=red];
    //c, 默认为椭圆
    d[shape=circle]; //园
    e[shape=triangle]; //三角形
    f[shape=polygon, sides=4, skew=0.5]; //平行四边形
    g[shape=polygon, distortion=0.5]; //梯形, 上边长
    h[shape=polygon, distortion=-.5]; //梯形, 下边长
}

有向图

digraph g {
  //edge[style=dashed]; //定义边的样式, 虚线
  node[peripheries=2, style=filled, color="#eecc80"];
  a->b [color=red, style=dashed]; //定义边的颜色, 红色 (b和方括号之间必须有空格)
  b->c; //箭头, 三角形; 箭尾, 菱形
  b->d [arrowhead=box]; //箭头, 长方形
  b->e [dir=none]; //没有箭头
  d->f [dir=both]; //双向箭头
  f->h [label=go]; //定义edge的标签
  f->k [arrowhead=diamond]; //更改箭头形状
  k->y [headlabel="哈哈", taillabel="洗洗"];
}

无向图

graph g {
  edge[style=dashed]; //定义边的样式, 虚线
  a -- b [color=red]; //定义边的颜色, 红色 (b和方括号之间必须有空格)
}

 ER图

digraph g {
graph [
rankdir = "LR"
];
node [
fontsize = "16"
shape = "ellipse"
];
edge [
];

"user" [
        label = "User| <id> id|username|password|last|status"
        shape = "record"
];

"profile" [
        label = "Profile| <id> id | name | sex | age | address | icq | msn"
        shape = "record"
];

user:id->profile:id [label="1:1"];

"category" [
        label = "Category| <id> id | <pid> pid | name | status"
        shape = "record"
];

category:pid->category:id [label="1:n"];

"article" [
        label = "Article| <id> id| <user_id> user_id | <cid> category_id | title | content | datetime | status"
        shape = "record"
];

article:user_id->user:id [label="1:n"];
article:cid->category:id [label="1:n"];

"feedback" [
        label = "Feedback| <id> id| <user_id> user_id | <article_id> article_id | title | content | datetime | status"
        shape = "record"
];

feedback:user_id->user:id [label="1:n"];
feedback:article_id->article:id [label="1:n"];

}

 复杂标签

 

 

digraph graphname{
    /* 把节点的形状设置为 record,默认的是圆角矩形 */
    node [shape = record];

    root [label = "left|middle|right"];
    left [label = "one|two"];
    right [label = "hello\nworld|{b|{c|d|e}|f}|g|h"];

    root -> left;
    root -> right;
}

 

3.3 高级使用

网上参考一篇博客,写的比较详细,对于很多应用场景都有提到: http://icodeit.org/2012/01/%E4%BD%BF%E7%94%A8graphviz%E7%BB%98%E5%88%B6%E6%B5%81%E7%A8%8B%E5%9B%BE/

但是,想要查询每个属性的信息,可以看官网的查询文档:
Node, Edge and Graph Attributes(属性):https://graphviz.gitlab.io/_pages/doc/info/attrs.html
Node Shapes(节点形状):https://graphviz.gitlab.io/_pages/doc/info/shapes.html
Arrow Shapes(箭头形状):https://graphviz.gitlab.io/_pages/doc/info/arrows.html

四、常见问题

4.1 编译问题

如果遇见以下错误:

image.png

解决:
1、编码问题。
把文件另存为,'utf-8'或'ANSI'(不涉及中文使用时),看是否编译出问题。
2、对于文件格式的识别。
将文件开头加2个空格,其识别的时候,对于第一个字符,在windows下会问题,源于文件的编码格式。

4.2 中文问题

修改文件,Graphviz2.37\etc\fonts\fonts.conf,安装的相对目录。
(1)文件修改
将下列代码:

 

<dir>#WINDOWSFONTDIR#</dir>
<dir>~/.fonts</dir>

修改为:

 

<dir>C:\WINDOWS\Fonts</dir>
<dir>~/.fonts</dir>

(2)文本设置
2.1 文本保存的编码为"utf-8"
2.2 文本中的字体设置
使用的dot文件按照规则属性,设置fontname属性即可:

 

fontname="Microsoft YaHei"
edge [fontname="Microsoft YaHei"];
node [fontname="Microsoft YaHei"];
digraph gvDemo3 {
    edge[fontname="Microsoft YaHei"]
    node[fontname="Microsoft YaHei"]
    graph[fontname="Microsoft YaHei"]

}

 

以上分别是全局、边、节点的设置。

可用的中文,有很多:

黑体:SimHei 
宋体:SimSun 
新宋体:NSimSun 
仿宋:FangSong 
楷体:KaiTi 
新细明体:PMingLiU
细明体:MingLiU
标楷体:DFKai-SB
微软正黑体:Microsoft JhengHei
微软雅黑体:Microsoft YaHei 

2.3 dot文件中的中文前后加空格
如:label="节点"应为label=" 节点 "

Java中使用

//GraphViz.java - a simple API to call dot from Java programs
/*$Id$*/
/*
******************************************************************************
*                                                                            *
*              (c) Copyright 2003 Laszlo Szathmary                           *
*                                                                            *
* This program is free software; you can redistribute it and/or modify it    *
* under the terms of the GNU Lesser General Public License as published by   *
* the Free Software Foundation; either version 2.1 of the License, or        *
* (at your option) any later version.                                        *
*                                                                            *
* This program is distributed in the hope that it will be useful, but        *
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
* or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public    *
* License for more details.                                                  *
*                                                                            *
* You should have received a copy of the GNU Lesser General Public License   *
* along with this program; if not, write to the Free Software Foundation,    *
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                              *
*                                                                            *
******************************************************************************
*/

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;

/**
* <dl>
* <dt>Purpose: GraphViz Java API
* <dd>
*
* <dt>Description:
* <dd> With this Java class you can simply call dot
*      from your Java programs
* <dt>Example usage:
* <dd>
* <pre>
*    GraphViz gv = new GraphViz();
*    gv.addln(gv.start_graph());
*    gv.addln("A -> B;");
*    gv.addln("A -> C;");
*    gv.addln(gv.end_graph());
*    System.out.println(gv.getDotSource());
*
*    String type = "gif";
*    File out = new File("out." + type);   // out.gif in this example
*    gv.writeGraphToFile( gv.getGraph( gv.getDotSource(), type ), out );
* </pre>
* </dd>
*
* </dl>
*
* @version v0.4, 2011/02/05 (February) -- Patch of Keheliya Gallaba is added. Now you
* can specify the type of the output file: gif, dot, fig, pdf, ps, svg, png, etc.
* @version v0.3, 2010/11/29 (November) -- Windows support + ability 
* to read the graph from a text file
* @version v0.2, 2010/07/22 (July) -- bug fix
* @version v0.1, 2003/12/04 (December) -- first release
* @author  Laszlo Szathmary (<a href="jabba.laci@gmail.com">jabba.laci@gmail.com</a>)
*/
public class Graphviz
{
/**
 * The dir. where temporary files will be created.
 */
//private static String TEMP_DIR = "/tmp"; // Linux
private static String TEMP_DIR = "c:/temp"; // Windows

/**
 * Where is your dot program located? It will be called externally.
 */
// private static String DOT = "/usr/bin/dot"; // Linux
private static String DOT = "C:\\Program Files (x86)\\Graphviz2.38\\bin\\dot.exe"; // Windows

/**
 * The source of the graph written in dot language.
 */
private StringBuilder graph = new StringBuilder();

/**
 * Constructor: creates a new GraphViz object that will contain
 * a graph.
 */
public Graphviz() {
}

/**
 * Returns the graph's source description in dot language.
 * @return Source of the graph in dot language.
 */
public String getDotSource() {
   return graph.toString();
}

/**
 * Adds a string to the graph's source (without newline).
 */
public void add(String line) {
   graph.append(line);
}

/**
 * Adds a string to the graph's source (with newline).
 */
public void addln(String line) {
   graph.append(line + "\n");
}

/**
 * Adds a newline to the graph's source.
 */
public void addln() {
   graph.append('\n');
}

/**
 * Returns the graph as an image in binary format.
 * @param dot_source Source of the graph to be drawn.
 * @param type Type of the output image to be produced, e.g.: gif, dot, fig, pdf, ps, svg, png.
 * @return A byte array containing the image of the graph.
 */
public byte[] getGraph(String dot_source, String type)
{
   File dot;
   byte[] img_stream = null;

   try {
      dot = writeDotSourceToFile(dot_source);
      if (dot != null)
      {
         img_stream = get_img_stream(dot, type);
         if (dot.delete() == false) 
            System.err.println("Warning: " + dot.getAbsolutePath() + " could not be deleted!");
         return img_stream;
      }
      return null;
   } catch (java.io.IOException ioe) { return null; }
}

/**
 * Writes the graph's image in a file.
 * @param img   A byte array containing the image of the graph.
 * @param file  Name of the file to where we want to write.
 * @return Success: 1, Failure: -1
 */
public int writeGraphToFile(byte[] img, String file)
{
   File to = new File(file);
   return writeGraphToFile(img, to);
}

/**
 * Writes the graph's image in a file.
 * @param img   A byte array containing the image of the graph.
 * @param to    A File object to where we want to write.
 * @return Success: 1, Failure: -1
 */
public int writeGraphToFile(byte[] img, File to)
{
   try {
      FileOutputStream fos = new FileOutputStream(to);
      fos.write(img);
      fos.close();
   } catch (java.io.IOException ioe) { ioe.printStackTrace();return -1; }
   return 1;
}

/**
 * It will call the external dot program, and return the image in
 * binary format.
 * @param dot Source of the graph (in dot language).
 * @param type Type of the output image to be produced, e.g.: gif, dot, fig, pdf, ps, svg, png.
 * @return The image of the graph in .gif format.
 */
private byte[] get_img_stream(File dot, String type)
{
   File img;
   byte[] img_stream = null;

try {
      img = File.createTempFile("graph_", "."+type, new File(Graphviz.TEMP_DIR));
      Runtime rt = Runtime.getRuntime();
      
      // patch by Mike Chenault
      String[] args = {DOT, "-T"+type, dot.getAbsolutePath(), "-o", img.getAbsolutePath()};
      Process p = rt.exec(args);
      
      p.waitFor();

FileInputStream in = new FileInputStream(img.getAbsolutePath());
      img_stream = new byte[in.available()];
      in.read(img_stream);
      // Close it if we need to
      if( in != null ) in.close();

if (img.delete() == false) 
         System.err.println("Warning: " + img.getAbsolutePath() + " could not be deleted!");
   }
   catch (java.io.IOException ioe) {
      System.err.println("Error:    in I/O processing of tempfile in dir " + Graphviz.TEMP_DIR+"\n");
      System.err.println("       or in calling external command");
      ioe.printStackTrace();
   }
   catch (java.lang.InterruptedException ie) {
      System.err.println("Error: the execution of the external program was interrupted");
      ie.printStackTrace();
   }

return img_stream;   }
/**
 * Writes the source of the graph in a file, and returns the written file
 * as a File object.
 * @param str Source of the graph (in dot language).
 * @return The file (as a File object) that contains the source of the graph.
 */
public File writeDotSourceToFile(String str) throws java.io.IOException
{
   File temp;
   try {
      temp = File.createTempFile("graph_", ".dot.tmp", new File(Graphviz.TEMP_DIR));
      FileWriter fout = new FileWriter(temp);
      fout.write(str);
      fout.close();
   }
   catch (Exception e) {
      System.err.println("Error: I/O error while writing the dot source to temp file!");
      return null;
   }
   return temp;
}

/**
 * Returns a string that is used to start a graph.
 * @return A string to open a graph.
 */
public String start_graph() {
   return "digraph G {" ;
}

/**
 * Returns a string that is used to end a graph.
 * @return A string to close a graph.
 */
public String end_graph() {
   return "}";
}

/**
 * Read a DOT graph from a text file.
 * 
 * @param input Input text file containing the DOT graph
 * source.
 */
public void readSource(String input)
{
 StringBuilder sb = new StringBuilder();
 
 try
 {
  FileInputStream fis = new FileInputStream(input);
  DataInputStream dis = new DataInputStream(fis);
  BufferedReader br = new BufferedReader(new InputStreamReader(dis));
  String line;
  while ((line = br.readLine()) != null) {
   sb.append(line);
  }
  dis.close();
 } 
 catch (Exception e) {
  System.err.println("Error: " + e.getMessage());
 }
 
 this.graph = sb;
}

} // end of class GraphViz
import java.io.File;

public class GTest {
    public static void main(String[] args){
        GTest gtest = new GTest();
        String[] nodes = {"A","B","C","D","E","F","G"};
        String[] preline = {"B -> A","D -> B","E -> D","C -> E","G -> C","F -> G"};
        gtest.start(nodes, preline);
    }
    private void start(String[] nodes,String[] preline){
           
           Graphviz gv = new Graphviz();
           //定义每个节点的style
           String nodesty = "[shape = polygon, sides = 6, peripheries = 2, color = lightblue, style = filled]";
           //String linesty = "[dir=\"none\"]";
           
           gv.addln(gv.start_graph());//SATRT
           gv.addln("edge[fontname=\"DFKai-SB\" fontsize=15 fontcolor=\"black\" color=\"brown\" style=\"filled\"]");
           gv.addln("size =\"8,8\";");
           //设置节点的style
           for(int i=0;i<nodes.length;i++){
               gv.addln(nodes[i]+" "+nodesty);
           }
           for(int i=0;i<preline.length;i++){
               gv.addln(preline[i]+" "+" [dir=\"none\"]");
           }
           gv.addln(gv.end_graph());//END
           //节点之间的连接关系输出到控制台
           System.out.println(gv.getDotSource());
           //输出什么格式的图片(gif,dot,fig,pdf,ps,svg,png,plain)
           String type = "png";
           //输出到文件夹以及命名
           File out = new File("C:/Users/fanghui/Desktop/GraphTest/test." + type);   // Linux
           //File out = new File("c:/eclipse.ws/graphviz-java-api/out." + type);    // Windows
           gv.writeGraphToFile( gv.getGraph( gv.getDotSource(), type ), out );
       }
}

 

控制台输出

 

输出生成的图片

 


参考 : 

https://www.jianshu.com/p/6d9bbbbf38b1

https://www.cnblogs.com/fanghuiplus/p/10072937.html

 

  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Graphviz是一个开源的图形可视化工具,可用于绘制各种图形,包括有向图、无向图和树等。在使用Python中的Graphviz库时,可以参考官方文档和一些实例来学习和使用该库。 在Python中使用Graphviz可以通过以下步骤来实现图形可视化: 1. 首先,确保已经安装了Graphviz软件,并将其添加到系统路径中。 2. 导入需要的库和模块,比如导入sklearn.tree中的export_graphvizgraphviz库。 3. 通过export_graphviz函数将模型转换为DOT格式的数据,其中模型可以是决策树等。 4. 使用graphviz.Source函数将DOT数据源导入到Graphviz对象中。 5. 可以选择将图形保存为文件,使用render函数,或者直接在Jupyter Notebook中显示图形。 下面是一个示例代码,展示了如何使用Graphviz库来生成决策树模型的可视化: ```python from sklearn.tree import export_graphviz import graphviz dot_data = export_graphviz(model, out_file=None, class_names=['0', '1']) graph = graphviz.Source(dot_data) graph.render('决策树可视化') ``` 这段代码将决策树模型转换为DOT格式,然后使用graphviz.Source函数将其导入到Graphviz对象中。最后,使用render函数将图形保存为文件,在本例中保存为"决策树可视化"。 需要注意的是,具体的使用方法可能因为版本和环境的不同而有所差异。因此,在使用Graphviz时,建议参考官方文档和一些实例,并根据自己的需求进行调整和使用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [[python] python模块graphviz使用入门](https://blog.csdn.net/LuohenYJ/article/details/106172201)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [Graphviz安装及使用:决策树可视化](https://blog.csdn.net/qq_45832050/article/details/109271806)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心歌技术

打赏不能超过你的早餐钱!!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值