杰瑞科技汇

Python Graphviz教程如何快速上手绘制流程图?

Python Graphviz 完整教程

Graphviz 是一个强大的图形可视化软件,它使用一种叫做 DOT 语言的简单文本描述来生成图形,Python 通过 graphviz 库可以非常方便地调用 Graphviz,将数据结构(如树、图、流程图)自动渲染成漂亮的图片。

Python Graphviz教程如何快速上手绘制流程图?-图1
(图片来源网络,侵删)

本教程将分为以下几个部分:

  1. 环境准备: 安装 Graphviz 和 Python 库。
  2. 基础入门: 创建你的第一个图形和节点。
  3. 深入图形元素: 学习添加边、设置属性。
  4. 子图与集群: 构建复杂的图形结构。
  5. 渲染与输出: 将图形保存为不同格式的文件。
  6. 进阶技巧: 使用 Source 对象、直接使用 DOT 语法等。
  7. 实战案例: 绘制一个决策树和流程图。
  8. 常见问题与解决方案

环境准备

在开始之前,你需要安装两样东西:

a) 安装 Graphviz 软件

这是核心,graphviz Python 库只是一个封装,真正负责绘图的是这个软件。

  • Windows:

    Python Graphviz教程如何快速上手绘制流程图?-图2
    (图片来源网络,侵删)
    1. 访问 Graphviz 官方下载页面
    2. 下载 Windows 安装包 (graphviz-release.msi)。
    3. 重要! 安装时,请务必勾选 "Add Graphviz to the system PATH for all users" 或 "Add Graphviz to the system PATH for the current user" 选项,这能让 Python 找到它。
    4. 安装完成后,重启你的终端或 IDE。
  • macOS (使用 Homebrew):

    brew install graphviz
  • Linux (Debian/Ubuntu):

    sudo apt-get update
    sudo apt-get install graphviz

验证安装: 打开终端或命令提示符,输入 dot -V,如果显示版本号,说明安装成功。

$ dot -V
dot - graphviz version 2.50.0 (2025-01-11)

b) 安装 Python 库

在你的 Python 环境中安装 graphviz 库。

Python Graphviz教程如何快速上手绘制流程图?-图3
(图片来源网络,侵删)
pip install graphviz

基础入门

让我们从一个最简单的例子开始:创建一个包含两个节点和一条边的图形。

from graphviz import Digraph # Digraph 用于有向图,Graph 用于无向图
# 1. 创建一个有向图对象
dot = Digraph(comment='My First Graph')
# 2. 添加节点
# 节点可以有 ID 和标签,标签是显示在图上的文字
dot.node('A', 'Start')
dot.node('B', 'End')
# 3. 添加边
# 边连接两个节点,可以指定边的标签
dot.edge('A', 'B', label='goes to')
# 4. 渲染并显示图形
# render() 方法会生成一个文件 (默认格式是 pdf)
# view=True 会在默认的图片查看器中打开生成的文件
dot.render('my-first-graph.gv', view=True) 

代码解释:

  • from graphviz import Digraph: 导入有向图类,如果需要无向图,请使用 from graphviz import Graph
  • dot = Digraph(...): 创建一个图形实例。
  • dot.node(...): 添加一个节点。
    • 第一个参数 'A' 是节点的唯一标识符(ID)。
    • 第二个参数 'Start' 是在图形中显示的标签。
  • dot.edge(...): 添加一条有向边。
    • 'A' 是源节点 ID。
    • 'B' 是目标节点 ID。
    • label='goes to' 是边上显示的文字。
  • dot.render(...): 将图形渲染成文件。
    • 'my-first-graph.gv' 是输出文件的名称(.gv 是 DOT 语言的扩展名)。
    • view=True 会自动打开生成的文件。

运行上述代码后,你会得到一个名为 my-first-graph.gv.pdf 的文件,并用你的默认 PDF 阅读器打开它,显示如下:


深入图形元素

Graphviz 的强大之处在于其丰富的属性设置。

a) 节点和边的属性

你可以通过 node_attredge_attr 设置全局默认属性,也可以在添加单个节点/边时使用 **attrs 参数进行覆盖。

from graphviz import Digraph
dot = Digraph(comment='Attributes Example')
# 设置全局节点属性:所有节点默认为矩形,填充色为浅蓝色
dot.node_attr = {'shape': 'box', 'style': 'filled', 'fillcolor': 'lightblue'}
# 设置全局边属性:所有边默认为虚线
dot.edge_attr = {'style': 'dashed'}
# 添加节点,并覆盖全局属性
dot.node('A', 'Start', shape='ellipse', fillcolor='green') # A 是椭圆,绿色
dot.node('B', 'Process')
dot.node('C', 'End', shape='diamond', fillcolor='red')   # C 是菱形,红色
# 添加边,并覆盖全局属性
dot.edge('A', 'B', label='Step 1', style='solid')     # 这条边是实线
dot.edge('B', 'C', label='Step 2')
dot.render('attributes-example.gv', view=True)

常用属性:

属性类别 属性名 描述 示例值
节点 shape 节点形状 'box', 'ellipse', 'circle', 'diamond', 'plaintext'
style 样式 'filled', 'dashed', 'rounded'
color 边框颜色 'red', '#FF0000'
fillcolor 填充颜色 'lightblue', 'lightgrey'
label 显示文本 'Hello'
label 边上显示的文本 'goes to'
style 样式 'solid', 'dashed', 'dotted'
color 颜色 'blue'
arrowhead 箭头形状 'normal', 'vee', 'dot'
fontsize 字体大小 '12'
图形 rankdir 布局方向 'LR' (从左到右), 'TB' (从上到下)
bgcolor 背景颜色 'white'

子图与集群

当图形变得复杂时,可以使用子图来组织结构。cluster 前缀可以给子图添加一个视觉边界。

from graphviz import Digraph
dot = Digraph(comment='Clusters Example')
# 设置整体布局方向为从左到右
dot.attr(rankdir='LR')
# 定义主流程
dot.node('Start', 'Start')
dot.node('Process1', 'Process 1')
dot.node('Process2', 'Process 2')
dot.node('End', 'End')
dot.edge('Start', 'Process1')
dot.edge('Process1', 'Process2')
dot.edge('Process2', 'End')
# 定义一个子图(集群)
# 'cluster_1' 是子图的 ID,'cluster' 前缀会自动创建一个矩形框
with dot.subgraph(name='cluster_1') as sub:
    sub.attr(label='Subprocess A') # 子图的标题
    sub.attr(color='blue')         # 子图的边框颜色
    sub.node('A1', 'Task A1')
    sub.node('A2', 'Task A2')
    sub.edge('A1', 'A2')
    # 将子图中的节点连接到主流程
    sub.edge('Process1', 'A1')
    sub.edge('A2', 'Process2')
# 定义另一个子图
with dot.subgraph(name='cluster_2') as sub:
    sub.attr(label='Subprocess B', color='green')
    sub.node('B1', 'Task B1')
    sub.node('B2', 'Task B2')
    sub.edge('B1', 'B2')
    # 连接到主流程
    sub.edge('Process2', 'B1')
    sub.edge('B2', 'End')
dot.render('clusters-example.gv', view=True)

渲染与输出

render() 方法非常灵活,可以控制输出格式和位置。

from graphviz import Digraph
dot = Digraph()
dot.node('A', 'Apple')
dot.edge('A', 'B')
# render() 的主要参数:
# filename: 输出文件名 (不带后缀)
# directory: 输出目录 (默认是当前目录)
# format: 输出格式 ('pdf', 'png', 'svg', 'jpg' 等)
# cleanup: 是否在渲染后删除 .gv 源文件 (默认为 True)
# view: 是否在渲染后自动打开文件 (默认为 False)
# 示例1: 生成 PNG 图片到 'output' 文件夹
dot.render('output/fruit_graph', format='png', cleanup=False)
# 示例2: 生成 SVG 图片,不自动打开,不删除源文件
dot.render('fruit_graph.svg', format='svg', view=False, cleanup=False)

支持的格式: pdf, png, svg, jpg, gif, bmp, dot (输出 DOT 源文件) 等。svg 格式在现代网页应用中特别有用。


进阶技巧

a) 使用 Source 对象

Source 对象非常方便,它可以直接解析一个 DOT 语言的字符串,而不需要逐个调用 node()edge() 方法。

from graphviz import Source
# 直接用 DOT 语法描述图形
dot_string = """
digraph {
    rankdir=LR;
    node [shape=box];
    A [label="Start"];
    B [label="Process"];
    C [label="End"];
    A -> B [label="step 1"];
    B -> C [label="step 2"];
}
"""
# 创建 Source 对象
src = Source(dot_string)
# 像之前一样渲染和显示
src.render('source-example.gv', view=True)
# 你也可以直接在 Jupyter Notebook 中显示它
# src

b) 循环结构

非常适合绘制树、列表等数据结构。

from graphviz import Digraph
dot = Digraph(comment='Tree Structure')
dot.attr(rankdir='TB') # 从上到下布局
# 根节点
dot.node('root', 'Root')
# 循环创建子节点
parent = 'root'
for i in range(3):
    child_id = f'child_{i}'
    dot.node(child_id, f'Child {i}')
    dot.edge(parent, child_id)
    # 为每个子节点再创建两个子节点
    for j in range(2):
        grandchild_id = f'grandchild_{i}_{j}'
        dot.node(grandchild_id, f'GC {i}-{j}')
        dot.edge(child_id, grandchild_id)
dot.render('tree-structure.gv', view=True)

实战案例

a) 绘制一个简单的决策树

from graphviz import Digraph
dot = Digraph(comment='Decision Tree')
dot.attr(rankdir='TB')
# 定义节点和边
dot.node('A', 'Is it raining?', shape='diamond')
dot.node('B', 'Take an umbrella', shape='box')
dot.node('C', 'Wear sunglasses', shape='box')
dot.edge('A', 'B', label='Yes')
dot.edge('A', 'C', label='No')
dot.render('decision-tree.gv', view=True)

b) 绘制一个流程图

from graphviz import Graph # 使用无向图
dot = Graph(comment='Process Flow')
dot.attr(rankdir='LR', splines='ortho') # splines='ortho' 使线条呈直角
dot.node('start', 'Start', shape='ellipse')
dot.node('input', 'Input Data', shape='parallelogram')
dot.node('process', 'Process Data', shape='box3d')
dot.node('decision', 'Valid?', shape='diamond')
dot.node('output', 'Output Result', shape='parallelogram')
dot.node('stop', 'Stop', shape='ellipse')
dot.edge('start', 'input')
dot.edge('input', 'process')
dot.edge('process', 'decision')
dot.edge('decision', 'output', label='Yes')
dot.edge('output', 'stop')
dot.edge('decision', 'process', label='No') # 循环回处理
dot.render('process-flow.gv', view=True)

常见问题与解决方案

Q1: ImportError: Failed to import Graphviz's executables.

原因: Python 找不到 Graphviz 软件。 解决方案:

  1. 确认已安装 Graphviz 软件:在终端运行 dot -V

  2. 检查系统 PATH:这是最常见的原因,确保 Graphviz 的 bin 目录(C:\Program Files\Graphviz\bin)已添加到系统的环境变量 PATH 中,修改后重启终端和 IDE

  3. 手动指定路径:如果无法修改 PATH,可以在代码中指定 Graphviz 的安装路径。

    import os
    from graphviz import Digraph
    # 设置 Graphviz 的安装路径
    os.environ["PATH"] += os.pathsep + 'C:/Program Files/Graphviz/bin'
    dot = Digraph()
    dot.node('A')
    dot.render('manual-path.gv', view=True)

Q2: graphviz.backend.execute.ExecutableNotFound: 'dot' not found

原因: 和 Q1 一样,是路径问题。 解决方案: 同上。

Q3: 渲染的图片中文字乱码或显示为方框。

原因: Graphviz 默认不支持中文字体,或者系统没有找到合适的字体。 解决方案:

  1. 指定中文字体: 在创建图形后,设置全局字体属性。

    from graphviz import Digraph
    dot = Digraph()
    # 指定一个系统中存在的中文字体
    dot.attr('node', fontname='SimHei') # 黑体
    dot.attr('edge', fontname='SimHei')
    dot.attr('graph', fontname='SimHei') # 图形标题字体
    dot.node('A', '你好')
    dot.node('B', '世界')
    dot.edge('A', 'B', label='连接')
    dot.render('chinese-font.gv', view=True)
  2. 确保字体文件存在: 确保你指定的字体(如 SimHei, Microsoft YaHei)确实安装在你的系统上。

Q4: 在 Jupyter Notebook / Google Colab 中使用 Graphviz。

解决方案:

  • 本地 Jupyter: 确保你的 Python 环境和系统 PATH 都配置正确,安装 graphviz 库后,通常可以直接 dot = Digraph(); dot 在单元格末尾输出图形。

  • Google Colab: Colab 的环境是隔离的,没有预装 Graphviz,你需要先安装软件和库。

    # 在 Colab 的一个单元格中运行
    !apt-get install graphviz
    !pip install graphviz
    # 然后在另一个单元格中正常使用
    from graphviz import Digraph
    dot = Digraph()
    dot.node('A')
    dot # 在单元格末尾输入变量名即可显示

通过这份教程,你应该已经掌握了使用 Python graphviz 库进行图形可视化的基本技能,从简单的节点边,到复杂的子图和属性设置,再到解决常见问题,Graphviz 是一个值得掌握的强大工具。

下一步:

  • 尝试用 Graphviz 可视化你自己的数据,比如文件目录结构、算法逻辑、或者状态机。
  • 探索 Graphviz 的 官方文档,了解更多高级功能和布局参数。
  • 学习 DOT 语言的更多语法,直接编写 .gv 文件然后用 Source 类加载,有时会更高效。
分享:
扫描分享到社交APP
上一篇
下一篇