4、DAG生成与可视化:snakemake --dag、--rulegraph、--filegraph

Pipeline写多了你就会发现,光靠读 Snakefile 根本看不出上下游关系。尤其规则一多,依赖链能绕成毛线团。

这时候就得靠 Snakemake 那三个可视化命令了:--dag、--rulegraph、--filegraph。说白了,它们帮你把规则之间的依赖关系画成图,一眼看清楚谁前谁后、谁输出了什么。

一句话区分:

  • --dag:以 文件 为节点,展示文件间的依赖关系——最细粒度。
  • --rulegraph:以 规则 为节点,展示规则间的执行顺序——最常用。
  • --filegraph:混合模式,包含文件和规则,但节点更多也更杂乱。

4.1 三个命令的用法与效果

我个人习惯先用 --rulegraph 扫一眼规则拓扑,确认没环再细查文件依赖。你别一开始就怼 --dag,小项目还行,上百个文件节点能刷屏刷到手软。

先看个基础用法:

snakemake --rulegraph | dot -Tpng > rulegraph.png
snakemake --dag | dot -Tpng > dag.png
snakemake --filegraph | dot -Tpng > filegraph.png

三个命令都输出 dot 格式文本,必须用 Graphviz 的 dot 命令渲染成图。没装 Graphviz?那你就只能看纯文本了——我就踩过这个坑,第一次跑 --dag 后直接输出到终端,屏幕刷了一版乱码。后来学乖了,先 pip 装好 graphviz,再走管道。

安装提醒:

Ubuntu/Debian:sudo apt install graphviz

macOS:brew install graphviz

Windows:去 graphviz.org 下安装包,或者用 conda install graphviz

举个例子。假设你有这么个 Snakefile:

rule all:
    input:
        "results/final_report.txt"

rule process_a:
    input:
        "data/raw_a.csv"
    output:
        "results/interim_a.csv"
    shell:
        "cp {input} {output}"

rule process_b:
    input:
        "data/raw_b.csv"
    output:
        "results/interim_b.csv"
    shell:
        "cp {input} {output}"

rule combine:
    input:
        a="results/interim_a.csv",
        b="results/interim_b.csv"
    output:
        "results/final_report.txt"
    shell:
        "cat {input.a} {input.b} > {output}"

--rulegraph 只会画出 规则节点:all → combine → process_a、process_b。因为 all 和 combine 之间有直接输入输出,process_a 和 process_b 是 combine 的依赖,它们之间没有边——谁先跑完都行。

--dag 会画出 文件节点:从 raw_a.csv、raw_b.csv 到 interim_a.csv、interim_b.csv,再到 final_report.txt,每一个中间产物都会出现在图上。

--filegraph 则把两种节点混着画,箭头也变多了,容易看花眼。我一般不推荐用它做日常调试,除非你要给老板展示“多么复杂”的工作流。

4.2 参数控制:只看子图、定向输出

项目大了以后,全量 DAG 可能画出来就是一团黑。Snakemake 提供了几个实用参数来瘦身:

参数 作用 示例
--target-rule 只显示能到达指定规则(或文件)的子图 --target-rule combine
--until 只显示执行到某个规则之前的所有依赖 --until process_a
--omit-from 从图中移除指定规则及其上游 --omit-from process_b
--omit-rule 只移除指定规则,保留上下游连接 --omit-rule all

举个例子。如果你只想看 combine 那一条链的上游,可以这么干:

snakemake --rulegraph --target-rule combine | dot -Tpdf > combine_sub.pdf

这样出来的图只有 all、combine、process_a、process_b 四个规则节点。但 process_a 和 process_b 之间没有边,也不会画 raw 文件——因为参数只限制“能到达目标规则”的节点,不能到达的就剪掉了。

小心自环(循环依赖):

如果一个规则的输出又被另一个规则当作输入,并且间接形成了环,Snakemake 在 --dag 时会报错。我曾经遇到过 A → B → C → A 的循环,当时查了整整两个小时才发现是文件命名搞反了。遇到 DAGError: cycle detected,先检查有没有文件在多个规则里既当 input 又当 output。

4.3 可视化格式与集成到报告

你画出来的图一般存成 PNG/PDF/SVG。我强烈推荐存成 SVG 或 PDF,缩放不糊,而且可以嵌入到 Snakemake 生成的 HTML 报告中。

# 存为 SVG,适合嵌入网页
snakemake --dag | dot -Tsvg > dag.svg

# 存为 PDF,矢量图,适合论文/PPT
snakemake --rulegraph | dot -Tpdf > rulegraph.pdf

要是你每次跑完都想自动生成 DAG 图,可以加一条规则到 Snakefile 里:

rule dag_plot:
    output:
        "reports/dag.svg"
    run:
        import subprocess
        cmd = "snakemake --dag | dot -Tsvg > {}".format(output[0])
        subprocess.run(cmd, shell=True, check=True)

这样 snakemake dag_plot 就会生成最新的 DAG 图。不过要注意,这条规则本身也在 DAG 中,你画的时候可能会把自己也画进去——我通常是单独在命令行跑,不在 Snakefile 里引用自己。

4.4 核心逻辑图:三种可视化对比

三种 DAG 可视化模式对比 --rulegraph 节点:规则名称 箭头:输入→输出 适用于:拓扑顺序 简洁度:★★★★★ --dag 节点:文件路径 箭头:输入文件→输出文件 适用于:细粒度审计 简洁度:★★★☆☆ --filegraph 节点:文件+规则混用 箭头:混合依赖 适用于:全局概览 简洁度:★★☆☆☆ rulegraph 示意 all ──→ combine combine ──→ process_a combine ──→ process_b dag 示意 raw_a.csv ──→ interim_a.csv raw_b.csv ──→ interim_b.csv interim_a.csv ──→ final_report.txt filegraph 示意 raw_a.csv ──→ process_a process_a ──→ interim_a.csv interim_a.csv ──→ combine 选择指南 快速排查循环依赖 → 用 --rulegraph 审计中间文件是否重复/缺失 → 用 --dag

4.5 实际项目中的避坑建议

  • 节点太多导致 SVG 渲染卡死: 我曾经在 500+ 规则的项目里跑 --dag,生成的 SVG 文件 200MB,浏览器直接崩溃。解决办法:加上 --target-rule 或者按模块拆分 DAG。
  • dot 命令找不到: 如果你用 conda 环境,记得 conda install graphviz,否则系统 dot 可能不在 PATH 里。我习惯在 Snakefile 里加一行 check_dot 规则来检测。
  • 颜色与形状: Snakemake 默认 DAG 图中,已完成的文件用绿色框,待运行的用白色框。如果你需要定制颜色,可以借助 --graphviz-flags 传递额外参数。

我的小技巧:

把每次重要运行的 DAG 图和日志一起归档到 reports/dag_{timestamp}.svg。这样回溯时能清楚知道当时的 pipeline 有没有变过,避免“明明改了代码但忘了更新 DAG”的尴尬。

可视化 DAG 不是花架子。它帮你快速定位循环依赖、发现孤立规则、确认输入文件路径是否正确。掌握这三个命令,审计 pipeline 的效率至少翻一倍。嗯,我就讲到这,快打开终端试试吧。