Python实战项目<2>使用Graphviz绘制流程框图

引言

当下有不少主流工具可用于绘制流程框图,例如大家熟知的 Visio,或是 WPS 内置的流程图功能。近期我在撰写《机器学习高阶 <2> 项目实战》系列博客时,恰好需要用 Python 实现流程图绘制 ------ 这便是我动笔写下本篇内容的契机。

在 Python 中使用 Graphviz 的核心是 "用代码定义图的节点 / 连接,调用 Graphviz 工具自动排版渲染",步骤分为环境准备代码使用两部分,下面详细说明。

一、先做好环境准备(必做)

Graphviz 需要 "Python 库 + 系统工具" 配合使用:

  1. 安装 Python 的 graphviz 库

打开命令提示符执行:

python 复制代码
python -m pip install graphviz

如下是使用Pycharm这个IDE在终端输入指令的图片:

2.安装系统级 Graphviz 工具

  • 安装时勾选 "Add to PATH"(或手动将安装目录的bin文件夹(如C:\Program Files\Graphviz\bin)添加到系统环境变量Path(如下是安装****Graphviz 工具 的教程)

下面的选项:

  • "Do not add Graphviz to the system PATH":不将 Graphviz 添加到系统 PATH 中
  • "Add Graphviz to the system PATH for all users":为电脑上的所有用户,将 Graphviz 添加到系统 PATH 中
  • "Add Graphviz to the system PATH for current user"(当前已选中):只为当前登录的用户,将 Graphviz 添加到系统 PATH 中

复选框 "Create Graphviz Desktop Icon":创建 Graphviz 的桌面图标

底部的 "Nullsoft Install System v3.06.1" 是这个安装程序的工具名称和版本,下方的 "上一步 (P)""下一步 (N)""取消 (C)" 是对应的操作按钮~

安装路径的选择:

安装成功后的界面:

  • 验证:重启终端后执行dot -V,能显示版本号则成功。

二、Python 中使用 Graphviz 的基础步骤

以 "画一个简单流程图" 为例,核心流程是:初始化图 → 添加节点 → 添加连接边 → 渲染输出

步骤 1:初始化图

先创建一个Digraph对象(表示 "有向图",适合流程图),可配置布局、字体等:

python 复制代码
from graphviz import Digraph

# 初始化有向图,设置布局方向(TB=从上到下)、中文支持
dot = Digraph(
    graph_attr={"rankdir": "TB", "fontname": "SimHei"},  # TB=从上到下布局,SimHei支持中文
    node_attr={"shape": "rect", "style": "filled", "fillcolor": "#f0f8ff"}  # 节点样式:矩形、浅蓝色填充
)
步骤 2:添加节点

dot.node("节点ID", "节点显示文本")添加节点(ID 是代码中区分节点的标识,文本是图中显示的内容):

python 复制代码
# 添加节点:ID分别为start、step1、step2、end
dot.node("start", "开始")
dot.node("step1", "执行任务A")
dot.node("step2", "执行任务B")
dot.node("end", "结束")
步骤 3:添加连接边

dot.edge("起点ID", "终点ID")定义节点之间的连接:

python 复制代码
# 连接节点:start → step1 → step2 → end
dot.edge("start", "step1")
dot.edge("step1", "step2")
dot.edge("step2", "end")
步骤 4:渲染输出

render()生成图片文件(支持 PNG、PDF 等格式),view=True会自动打开图片:

python 复制代码
# 生成PNG图片,文件名为"simple_flow"
dot.render("simple_flow", format="png", view=True)
print("流程图已生成:simple_flow.png")

三、进阶:自定义样式(可选)

可以调整节点颜色、边的样式、添加标签等,比如:

python 复制代码
from graphviz import Digraph

dot = Digraph(graph_attr={"rankdir": "TB", "fontname": "SimHei"})

# 自定义节点样式
dot.node("a", "重要节点", fillcolor="#ffcccc", style="filled")  # 红色填充
dot.node("b", "普通节点", fillcolor="#f0f8ff", style="filled")

# 自定义边:加标签、虚线样式
dot.edge("a", "b", label="依赖关系", style="dashed", color="#666666")

dot.render("custom_style", format="png", view=True)

常用场景示例

除了流程图,还可以画树形结构、依赖图等,比如画一个二叉树:

python 复制代码
from graphviz import Digraph

dot = Digraph(graph_attr={"rankdir": "TB", "fontname": "SimHei"})
dot.node("root", "根节点")
dot.node("left", "左子节点")
dot.node("right", "右子节点")

dot.edge("root", "left")
dot.edge("root", "right")

dot.render("binary_tree", format="png", view=True)

四、项目实战

这段代码是一个Graphviz 环境诊断工具,专门用于在 Windows 系统中自动检测 Graphviz 的安装、配置及可用性问题,解决用户在使用 Python 调用 Graphviz 时常见的报错(如找不到 dot.exe、环境变量未配置、Python 库未安装等)。它不仅能定位问题,还会给出明确的修复提示,并通过实际测试验证 Graphviz 是否能正常工作。

python 复制代码
# 诊断脚本:diagnose.py
import os
import sys
import subprocess


def check_python_version():
    print(f"Python 版本: {sys.version}")
    print()


def check_graphviz_installation():
    print("检查 Graphviz 安装...")

    # 检查常见安装路径
    possible_paths = [
        r"C:\Program Files\Graphviz\bin",
        r"C:\Program Files (x86)\Graphviz\bin",
        r"C:\Graphviz\bin",
    ]

    found = False
    for path in possible_paths:
        dot_exe = os.path.join(path, "dot.exe")
        if os.path.exists(dot_exe):
            print(f"✓ 找到 Graphviz: {path}")
            found = True

            # 测试版本
            try:
                result = subprocess.run([dot_exe, "-V"],
                                        capture_output=True,
                                        text=True,
                                        timeout=5)
                if result.returncode == 0:
                    print(f"  Graphviz 版本: {result.stdout.strip()}")
                else:
                    print(f"  ✗ 无法获取版本信息")
            except:
                print(f"  ✗ 无法执行 dot 命令")

    if not found:
        print("✗ 未找到 Graphviz")
        print()
        print("请安装 Graphviz:")
        print("1. 访问 https://graphviz.org/download/")
        print("2. 下载 Windows 版本")
        print("3. 安装时务必勾选 'Add Graphviz to the system PATH for all users'")

    return found


def check_python_packages():
    print("\n检查 Python 包...")

    packages = ["graphviz"]

    for package in packages:
        try:
            if package == "graphviz":
                import graphviz
                version = graphviz.__version__ if hasattr(graphviz, '__version__') else "未知"
                print(f"✓ {package}: {version}")
            else:
                __import__(package)
                print(f"✓ {package}: 已安装")
        except ImportError:
            print(f"✗ {package}: 未安装")
            if package == "graphviz":
                print("  运行: pip install graphviz")


def check_path_environment():
    print("\n检查 PATH 环境变量...")

    path = os.environ.get("PATH", "")
    path_dirs = path.split(os.pathsep)

    graphviz_found = False
    for dir_path in path_dirs:
        if "graphviz" in dir_path.lower() and os.path.exists(os.path.join(dir_path, "dot.exe")):
            print(f"✓ Graphviz 在 PATH 中: {dir_path}")
            graphviz_found = True

    if not graphviz_found:
        print("✗ Graphviz 不在 PATH 中")

    return graphviz_found


def run_simple_test():
    print("\n运行简单测试...")

    # 创建最简单的图表
    dot_source = """
    digraph G {
        A -> B;
        A -> C;
        B -> D;
        C -> D;
    }
    """

    # 保存为 .dot 文件
    with open("test_graph.dot", "w") as f:
        f.write(dot_source)

    print("✓ 已创建测试文件: test_graph.dot")

    # 尝试使用 dot 命令转换
    try:
        result = subprocess.run(
            ["dot", "-Tpng", "-otest_graph.png", "test_graph.dot"],
            capture_output=True,
            text=True,
            timeout=10
        )

        if result.returncode == 0:
            print("✓ 成功生成 test_graph.png")
            if os.path.exists("test_graph.png"):
                print(f"  文件大小: {os.path.getsize('test_graph.png')} 字节")
            return True
        else:
            print(f"✗ 生成失败: {result.stderr}")
            return False
    except FileNotFoundError:
        print("✗ 找不到 dot 命令")
        return False
    except Exception as e:
        print(f"✗ 测试失败: {e}")
        return False


if __name__ == "__main__":
    print("=" * 60)
    print("Graphviz 诊断工具")
    print("=" * 60)

    check_python_version()

    path_ok = check_path_environment()
    install_ok = check_graphviz_installation()
    check_python_packages()

    if install_ok:
        test_ok = run_simple_test()
        if test_ok:
            print("\n" + "=" * 60)
            print("✓ 所有检查通过!")
            print("=" * 60)
        else:
            print("\n" + "=" * 60)
            print("✗ 测试失败,请检查 Graphviz 安装")
            print("=" * 60)
    else:
        print("\n" + "=" * 60)
        print("✗ 请先安装 Graphviz")
        print("=" * 60)

代码采用模块化设计,将诊断逻辑拆分为多个独立函数,按"基础环境→配置检查→软件安装→依赖库→实际功能测试"的故障排查逻辑逐步执行,既符合开发者排查问题的思维习惯,也让代码结构清晰、易维护。

功能模块拆分(每个函数负责单一诊断任务)

函数名 核心功能
check_python_version 打印当前 Python 版本,排查 Python 版本兼容性问题(基础环境检查)
check_path_environment 检查系统PATH环境变量中是否包含 Graphviz 的bin目录(关键配置检查)
check_graphviz_installation 遍历 Windows 系统中 Graphviz 的常见安装路径,检测是否安装了 Graphviz,并尝试获取版本信息
check_python_packages 检查 Python 的graphviz库是否安装及版本(依赖库检查)
run_simple_test 创建简单的 dot 文件,调用dot命令生成 PNG 图片,验证 Graphviz 实际功能是否可用

关键设计细节

  • 自动化路径检测check_graphviz_installation函数预设了 Windows 系统中 Graphviz 的常见安装路径(如C:\Program Files\Graphviz\bin),无需用户手动指定,提升易用性。
  • 友好的用户反馈 :使用/符号直观显示检查结果,失败时给出具体的解决步骤(如 Graphviz 下载地址、安装时勾选 PATH 的提示),新手能直接参考。
  • 异常处理与健壮性 :在执行subprocess调用(如dot -V、生成图片)时加入异常捕获,避免脚本因个别错误崩溃,确保诊断流程能完整执行。
  • 实际功能验证 :不只是停留在 "配置检查" 层面,run_simple_test函数会创建测试文件并尝试生成图片,确保 Graphviz 能真正工作,而非仅表面配置正确。
  • 执行逻辑串联:在主程序中按顺序执行所有诊断函数,先检查基础环境,再验证实际功能,最后根据检查结果给出最终结论(如 "所有检查通过" 或 "请先安装 Graphviz")。

控制台的结果:

运行结果:

五、常见的错误解决方式:

选择 "Add Graphviz to the system PATH for current user" 本身是没问题的,但直接去 PyCharm 运行代码大概率会仍报错 ------ 核心原因是:PyCharm 启动时会读取当时的系统环境变量,而你是安装 Graphviz 后才添加的 PATH,已打开的 PyCharm 还没加载到新的环境变量

解决办法很简单:

  1. 完全关闭 PyCharm(包括后台进程)
  2. 重新打开 PyCharm,再运行代码。

如下PyCharm 里检查环境变量是否已经包含了 Graphviz 的路径:

方法 1:用代码直接打印系统 PATH(最直观)

你可以在 PyCharm 里新建一个临时 Python 文件,运行以下代码,直接查看系统 PATH 中是否包含 Graphviz 的bin目录(比如C:\Program Files\Graphviz\bin):

python 复制代码
import os

# 获取系统的PATH环境变量
system_path = os.environ.get("PATH", "")
# 按分号分割PATH里的所有路径
path_list = system_path.split(";")

# 打印所有路径,或筛选包含"Graphviz"的路径
print("系统PATH中包含的路径:")
for path in path_list:
    if "Graphviz" in path:  # 筛选Graphviz相关路径
        print(f"找到Graphviz路径:{path}")

如果运行后输出了类似"找到Graphviz路径:C:\Program Files\Graphviz\bin"的内容,说明 PATH 已包含;如果没有输出,说明环境变量还没加载到 PyCharm 中(需要重启 PyCharm)

方法 2:通过 PyCharm 的 "运行配置" 查看环境变量

步骤如下:

  1. 打开 PyCharm,点击顶部菜单栏的 Run(运行)→ Edit Configurations(编辑配置)
  2. 在弹出的窗口中,选择你当前运行代码对应的配置(比如 Python 脚本的配置);
  3. 找到右侧的 Environment variables(环境变量) 选项,点击它旁边的 文件夹图标(或 "..." 按钮);
  4. 在新窗口中,找到PATH变量,点击展开它的内容,查看列表中是否包含 Graphviz 的bin目录。

补充说明

如果检查后发现 PATH 里没有 Graphviz 路径,只需完全关闭 PyCharm(包括后台进程)再重新打开,PyCharm 会重新加载系统环境变量,此时再检查就能看到了。

相关推荐
ljuncong4 小时前
python的装饰器怎么使用
开发语言·python
2501_944875515 小时前
Go后端工程师
开发语言·后端·golang
该用户已不存在5 小时前
没有这7款工具,难怪你的Python这么慢
后端·python
听风吟丶5 小时前
Java 反射机制深度解析:从原理到实战应用与性能优化
java·开发语言·性能优化
serve the people5 小时前
tensorflow 零基础吃透:RaggedTensor 的不规则形状与广播机制 2
人工智能·python·tensorflow
Hello.Reader5 小时前
Flink ML 基本概念Table API、Stage、Pipeline 与 Graph
大数据·python·flink
chen_note5 小时前
Python面向对象、并发编程、网络编程
开发语言·python·网络编程·面向对象·并发编程
她说彩礼65万5 小时前
C# params使用
开发语言·c#·log4j
信看5 小时前
树莓派CAN(FD) 测试&&RS232 RS485 CAN Board 测试
开发语言·python