资讯动态

用LaTeX Forest宏包高效绘制思维导图:从零到进阶实战指南

发布时间:2026/10/20 8:59:53 来源:尧图企业网站定制
1. 为什么用LaTeX画思维导图从文档排版一体化说起你有没有遇到过这种尴尬一篇论文或技术报告写完了需要用一张思维导图总结章节结构或者课件里要放一张技术路线图。大多数人会先打开在线脑图工具或PPT画好之后再截图贴进LaTeX文档。结果图片风格和正文字体完全是两套体系改一轮内容就要重新截图导出的图清晰度还经常不够。后来我彻底换成了直接在 LaTeX 里用 Forest 宏包画思维导图终于不用再折腾截图和对齐这件事了。Forest 是 LaTeX 生态里专门用来画树状结构的宏包底层基于 TikZ但语法比原生 TikZ 树简洁得多。它解决的问题很明确用纯代码描述树形层级自动计算节点坐标、连线和分支间距输出高保真的矢量 PDF。对于思维导图、组织架构图、技术路线图、知识图谱这类场景Forest 是当前 LaTeX 生态里最顺手的方案。这篇文章会从零开始讲 Forest 的用法先解释为什么值得迁移到它再给最小可编译示例然后拆解布局参数、样式语法用一张Python学习路线的实战案例走通全流程最后分享我多年使用中踩过的坑和进阶玩法。看完你就能完全脱离在线脑图工具在自己的 LaTeX 工作流里画出风格统一的思维导图。1.1 多数人做思维导图的工具到底差在哪思维导图工具大体分三类在线协作工具、PPT 画图、Word 或专业制图软件。它们的共同痛点是和 LaTeX 文档体系割裂。在线工具导出的图片是一整张位图或嵌入字体不完整的矢量图放进 LaTeX 后遇到字体统一性、清晰度、公式引用、版本管理这四类问题时会特别麻烦。工作流上也割裂。画图是一个单独系统改文字、改结构、换配色都要回到那个工具里操作。如果是多人协作还好个人写文档时来回切换工具的注意力消耗很容易让人放弃维护思维导图最终文档里只有一张过期的图。还有一点容易被忽略在线工具的自动布局通常只能拖拽记录位置想精细调整这一层的间距、这个分支的连线拐点时非常费劲。Forest 在这方面的定位完全不同——它把布局参数化所有间距、方向、连线形式都是代码里的键值对改哪里一目了然版本控制工具里也能清晰看到差异。1.2 Forest 与原生 TikZ 树、qtree、手工布局的对比LaTeX 世界里画树其实不止 Forest 一个选择。原生 TikZ 支持graph语法和tree风格但写起来非常啰嗦每个节点要写坐标或父子关系宏样式一复杂代码就爆炸。qtree 宏包在语言学领域用得多适合短语结构树但它的布局算法简单层级一深就挤在一起。手工用 TikZ 的node和edge一根线一根线画自由度最高但那是画图不是生成思维导图。Forest 的核心价值在于它实现了完整的树布局算法。你只要写出节点嵌套关系和层级选项它会自动处理子节点排列、避免重叠、连线拐弯这些底层问题。对比下来除非你要画的是完全不规则的自由图否则在树形结构这个范畴内Forest 几乎总是性价比最高的选择。下面是几个常见方案的能力对比方案语法复杂度自动布局定制性适合场景Forest低强自动避让与对齐高思维导图、层级树、路线图原生 TikZ tree高弱要手动调坐标高简单树、嵌入其他 TikZ 图qtree低弱层级深容易挤中语言学短语结构树手工 TikZ 节点连线很高无最高自定义结构图、拓扑图2. 零基础起步环境配置与第一张 Forest 图2.1 环境需要什么你只需要一个完整的 LaTeX 发行版比如你自己电脑上常用的 TeX Live 或 MiKTeX。LaTeX 发行版自带 forest 宏包不需要额外安装。如果你用的是精简配置且编译报Package forest not found在终端执行tlmgr install forest安装即可。在线共享编译平台也很方便把代码贴进去选择对应编译器就能出图。下面这份代码是目前我用来快速验证 Forest 语法的最小模板编译后会自动裁剪成内容大小的 PDF非常适合单独生成一张思维导图再嵌入主文档\documentclass[border10pt]{standalone} \usepackage[edges]{forest} \begin{document} \begin{forest} for tree { grow 0, draw, rounded corners 2pt, inner sep 3pt, } [根节点 [子节点A [叶A1] [叶A2] ] [子节点B [叶B1] ] ] \end{forest} \end{document}编译方式是xelatex 文件名.tex或pdflatex 文件名.tex。如果文档里有中文必须用 XeLaTeX 编译并配合ctex宏包这一点后面踩坑部分会细说。2.2 Forest 语法最小集括号嵌套加选项Forest 的语法核心就两个东西方括号嵌套表示父子关系选项列表调整样式和布局。先看结构[根节点 [子节点A [叶A1] [叶A2] ] ]这是一棵标准的树根节点下挂子节点子节点下挂叶子。方括号内可以继续嵌套层数不限。再看向导式的选项for tree { grow 0, draw, rounded corners 2pt, }for tree表示后面括号里的选项会应用到这棵树的所有节点。grow 0表示整棵树的生长方向是 0 度角也就是向右展开。如果不写默认朝下生长。draw给每个节点加上边框rounded corners让边框圆角。节点自己的样式写在节点名字后面、右方括号之前。比如[重点节点, fill yellow!20, text red, draw red!50 [普通子节点] ]这种写法的作用范围只有当前节点子节点不会继承它的颜色和填充样式。如果你想给某个子树整体换风格要用后面会提到的for subtree或for tree嵌套。2.3 编译之后再怎么用嵌入正文与导出图片用standalone文档类的好处是输出 PDF 会自动裁剪到内容边界没有多余白边。在主文档里直接用\includegraphics{思维导图.pdf}引入即可图片风格天然和文档统一。如果投稿系统要求图片格式可以先把 PDF 转成高清 PNG。命令行工具很多比如用pdftoppmpdftoppm -png -r 300 思维导图.pdf 输出文件名-r 300表示 300 DPI满足一般印刷要求。这里的核心优势是源文件是矢量的想导出多大分辨率都清晰不会像在线工具截图那样发虚。3. 核心选项拆解让分支布局和间距服服帖帖很多人第一次用 Forest 画出来的图丑不是节点样式差而是对布局参数不熟悉。Forest 的自动布局确实好用但它只是按你给的参数进行计算不会自动替你判断哪种间距和方向更适合当前内容。这一节我把最影响布局效果的几个参数讲透。3.1 先理解四个参数grow、l sep、s sep、fork sep第一个是grow它控制树的整体生长方向取值是角度。0 表示向右90 表示向上180 表示向左-90 表示向下默认是向下。思维导图推荐向右展开因为人的阅读习惯是从左到右根节点放最左侧分支向右延伸视觉上最舒服。第二个是l sep它控制层级之间的距离。这里的l是 level 的意思父子节点之间的间距。默认太小的时候父子节点的文字会贴在一起调大之后观察每层之间的留白即可。第三个是s sep它控制兄弟节点之间的间距。兄弟节点太多、文字太长时会重叠这时优先增大s sep。注意s sep的实际效果是相邻节点之间的最小分离距离不只是字面间距所以遇到重叠时它是最直接的解药。第四个是fork sep它只在启用折线连线时生效表示父节点往下到拐弯点的垂直距离。可以理解为折线从父节点出来先垂直走多远再水平拐到子节点。这个值会影响分支的紧凑感太小折线拐点贴近父节点文字太大分支感觉松散。3.2 四种最常见的布局形态第一种从左到右的阅读型树适合技术路线图和学习笔记for tree { grow 0, l sep 12mm, s sep 4mm, }第二种从上到下的组织架构树或目录树适合比较正式的结构表达for tree { grow -90, l sep 10mm, s sep 5mm, }第三种圆角气泡风格适合课件和汇报。用rounded corners配合填充色for tree { grow 0, rounded corners 4pt, draw teal!60, fill teal!5, }第四种用tier让不同分支的同一层级拥有统一的水平对齐线适合强调层级关系的思维导图。比如左到右生长时希望所有第一层子节点都在同一条竖直线上for tree { grow 0, tier/.option level, }tier会把同一 level 的节点放入相同的对齐梯队效果就像多棵子树被拉直整体看着非常规整。3.3 节点内容换行、公式、颜色一次讲清Forest 的节点不仅能写文字还能放公式、代码片段和表格这是它优于在线工具的杀手级特性。例如在思维导图节点里写数学公式[损失函数 [$\text{ReLU}(x)\max(0,x)$] [$L_2$ 正则] ]写长文本时节点不会自动换行需要指定宽度。最常见的做法是在for tree里设置for tree { text width 22mm, align center, }text width是 TikZ 节点原生的参数Forest 直接透传。设置了宽度后节点内容超过宽度会自动换行align控制对齐方式常用center或left。需要注意align是 TikZ 文本对齐键在 Forest 节点中也能用。给节点配色也很简单[关键结论, fill orange!20, text black, draw orange!60]复杂颜色可以定义成 TikZ 样式比如在导言区写\tikzset{mystyle/.style {draw blue!50, fill blue!10, rounded corners}}然后在节点里直接用mystyle。3.4 连线也是样式颜色、线宽、虚线、折线连线是思维导图观感的重要组成部分。Forest 中通过edge选项控制它接受 TikZ 路径样式。例如for tree { edge {gray!70, line width 1pt, dashed} }会让整棵树的所有连线变成灰色虚线。想要不同子树区分线色可以在子节点上单独写edge {red}它只影响从该节点通往它子节点的连线。如果使用\usepackage[edges]{forest}加载了 edges 库可以使用折线连线。折线让思维导图看起来更像正经结构图而不是曲线乱飞。设置方式很简单\begin{forest} forked edges, for tree { grow 0, fork sep 3mm, l sep 10mm, s sep 4mm, } [根节点 [分支A] [分支B] ] \end{forest}forked edges是整个环境的选项配合fork sep控制拐弯位置。我实际用下来左到右的思维导图配折线是最出效果的组合。4. 实战一场从零画一张Python学习路线思维导图4.1 先写树结构再写样式我的习惯永远是先把树的层级关系在文本编辑器里敲出来不急着调样式。因为 Forest 的布局是自动的只要层级关系正确最终图基本不会结构混乱。以Python学习路线为例目标是一张适合放进学习笔记或课程大纲的图。我先把层级写成一棵纯文本树Python学习路线 ├─ 基础语法 │ ├─ 变量与类型 │ ├─ 条件与循环 │ ├─ 函数 │ └─ 异常处理 ├─ 核心数据结构 │ ├─ 列表/元组 │ ├─ 字典/集合 │ └─ 推导式 ├─ 文件与 IO │ ├─ 文本文件 │ ├─ JSON/CSV │ └─ os 与 pathlib ├─ 面向对象 │ ├─ 类与实例 │ ├─ 继承 │ └─ 魔术方法 ├─ 常用第三方库 │ ├─ NumPy │ ├─ Pandas │ ├─ Matplotlib │ └─ Requests ├─ 工程实践 │ ├─ 代码规范 │ ├─ 单元测试 │ └─ 虚拟环境 └─ 项目实战 ├─ 爬虫 ├─ 数据分析 └─ Web 后端这一步不需要考虑任何排版细节只保证两件事层级嵌套正确、节点命名清晰。4.2 完整源码与逐段解释把上面的结构翻译成 Forest 语法加上中文支持和布局参数完整代码如下\documentclass[border12pt]{standalone} \usepackage[edges]{forest} \usepackage{ctex} \begin{document} \begin{forest} for tree { grow 0, l sep 11mm, s sep 3mm, fork sep 3mm, draw blue!50, rounded corners 2pt, text width 22mm, align center, font \small, if level 0 {text width 28mm, font \normalsize\bfseries} {text width 20mm}, } [Python 学习路线 [基础语法 [变量与类型] [条件与循环] [函数] [异常处理] ] [核心数据结构 [列表/元组] [字典/集合] [推导式] ] [文件与 IO [文本文件] [JSON/CSV] [os 与 pathlib] ] [面向对象 [类与实例] [继承] [魔术方法] ] [常用第三方库 [NumPy] [Pandas] [Matplotlib] [Requests] ] [工程实践 [代码规范] [单元测试] [虚拟环境] ] [项目实战 [爬虫] [数据分析] [Web 后端] ] ] \end{forest} \end{document}几个关键点在代码里体现得很清楚grow 0让整棵树从左侧根节点向右展开适合放正文页内。l sep和s sep分别控制层级间距与兄弟间距这里给的是经过实测比较舒服的数值。forked edges配合fork sep让连线呈现规整的折线形态。text width统一设置节点宽度后节点文字会自动换行。但根节点文字更长所以我用if level 0做一个条件判断根节点的宽度设为 28mm 且加粗其余节点宽度压缩到 20mm。这是 Forest 条件选项的简单用法语法很直观if 条件 {为真时的选项} {为假时的选项}。4.3 效果实测与我的调整记录第一次编译这张图时我发现常用第三方库有四个叶子节点而基础语法也有四个叶子节点但两个分支的叶子文字长度不同导致右侧叶子行尾不在一条垂直线上视觉上略乱。我最初没有加tier/.option level所以各子树的同级节点并不会强制对齐到同一竖线。想要更整齐的画面可以在for tree里加上一行tier/.option level,这样所有第一层节点、第二层节点、第三层节点都会对齐到各自对应的竖直线上。加了之后整张图的右侧边缘就像被一把尺子裁过一样非常整齐。另一个小问题是os 与 pathlib文字较长20mm 宽度下换行成了两行和旁边单行的JSON/CSV高度不一致。处理办法是给它单独设置更大宽度[os 与 pathlib, text width 26mm]或者把这一支的文字缩短成os/pathlib。两种方案都行我在实际文档里选择后者因为图中的文字应尽量简洁详细表述放进正文比较好。5. 三套可直接抄作业的样式模板与封装技巧5.1 学术论文友好黑白克制模板期刊论文插图最忌讳花哨Forest 默认的黑色边框就很好。我常用这套模板处理论文里的研究框架图\begin{forest} for tree { grow 0, draw black!80, line width 0.6pt, rounded corners 2pt, text width 24mm, align center, l sep 10mm, s sep 3mm, edge {black!60, line width 0.6pt}, fork sep 2mm, } [研究框架 [理论层 [概念定义] [理论模型] ] [方法层 [数据准备] [算法设计] [实验验证] ] [结论层 [结果分析] [未来工作] ] ] \end{forest}注意这里把edge颜色也调成black!60比节点边框浅一点既保持单色统一又让连线不抢眼。论文插图建议在根节点和一级子节点处加粗if level 1 {font \small\bfseries} {}5.2 课程课件友好圆角彩色模板彩色模板的要点是控制颜色数量别超过三种主色否则会显得乱。我常用青色、蓝色、橙色三种色相\begin{forest} for tree { grow 0, draw teal!60, fill teal!8, rounded corners 4pt, text width 22mm, align center, l sep 10mm, s sep 3mm, forked edges, fork sep 3mm, } [核心模块 [用户层, for subtree {draw blue!50, fill blue!8} [登录] [注册] [权限] ] [业务层, for subtree {draw orange!60, fill orange!10} [订单] [支付] [库存] ] ] \end{forest}这里用了一个很有用的技巧在某个子节点上写for subtree {...}里面定义的选项会应用到以该节点为根的整棵子树。整套图一个主色但不同分支用深浅和色相区分信息层次一下就出来了。5.3 会议纪要友好紧凑小字模板开会时我常用 Forest 做一页纸的结构笔记要求密度高、能塞尽量多节点。这时把字体调小、间距收紧\begin{forest} for tree { grow 0, font \scriptsize, text width 18mm, align left, l sep 6mm, s sep 1mm, inner sep 2pt, draw gray!30, rounded corners 1pt, edge {gray!30}, } [Q3 计划 [目标 [营收] [新增用户] ] [风险 [政策] [竞争] ] [资源 [人力] [预算] ] ] \end{forest}如果这张图要放进 A4 页面可以在森林环境开头加一个scale选项\begin{forest} scale 0.8, for tree { ... }scale会把整棵 TikZ 树按比例缩放适合内容太多又不想改参数的情况。注意纯粹放大缩小不影响文字的相对布局所以一般情况下没问题。5.4 用 \forestset 封装专属样式每次写文档都复制粘贴一长串for tree选项很烦更好的做法是用\forestset把这些选项定义成一套命名样式\forestset{ mytree/.style { for tree { grow 0, l sep 10mm, s sep 3mm, forked edges, draw teal!50, rounded corners 2pt, text width 22mm, align center, }, }, }然后在导言区或文档开头定义好之后用的时候就一句话\begin{forest} mytree, [根节点 [子A] [子B] ] \end{forest}需要调整细节时还能在mytree,后面追加其他选项覆盖同名键\begin{forest} mytree, s sep 5mm, ...这个封装思路把我的所有思维导图文档从每次复制 20 行配置变成了一行样式名长期维护省心太多。6. 踩坑记录中文乱码、文字溢出、节点重叠与跨页问题用 Forest 这么多年踩过的坑都集中在环境、换行、间距和页面边界这几个点上。6.1 中文乱码问题出在编译器而不是 Forest第一个坑是中文显示成乱码或直接编译报错。Forest 本身完全支持中文但必须用 XeLaTeX 或 LuaLaTeX 编译并加载ctex宏包处理字体和断行\usepackage{ctex}如果坚持用 pdflatex要么改用CJKutf8配合 CJK 字体要么就得忍受各种字符兼容问题。我的建议是不要挣扎直接切 XeLaTeX。很多在线共享编译平台默认编译器就是 pdflatex上传中文文件后点击编译会失败这时把编译器切换成 XeLaTeX 就能跑通。最省心的一套环境配置是编辑器文件编码统一用 UTF-8导言区加\usepackage{ctex}编译命令用xelatex 文件名.tex6.2 文字溢出text width 从未如此重要Forest 节点里的长文本默认不换行稍微写长一点就会撑破边框甚至溢出页面。我见过很多新手在这里栽跟头。解决方案分两步第一步在for tree里统一设置节点宽度text width 22mm, align center,第二步需要把内容改成近似手写时给该节点单独设置文本宽度。注意text width只影响换行宽度不改变节点框大小节点框会随内容自动伸缩。踩过几次之后我养成了一个习惯任何有可能出现长标题的节点都在for tree中先写text width避免编译出来再回头补。6.3 节点重叠按顺序检查三个间距节点重叠是 Forest 自动布局中比较常见的问题。我的排查顺序是先看s sep兄弟节点之间是否过于拥挤小就调大再看l sep父子节点之间是否因为层级距离过近而贴在一起最后看fork sep折线距离是否合适。如果s sep调大后分支拉得太宽可以试着把同级节点对齐方式改成首尾对齐使用calign first或calign edge。这些参数控制子节点在父节点下方的排列方式在左侧分支多的图中能有效压缩宽度。6.4 整图跨页standalone 是最优雅的解法还有一个容易忽略的问题Forest 生成的图是一整张 TikZ 图不能像文字那样跨页。如果思维导图内容太多超出页面宽度直接嵌入正文排版会很难看。我的做法是思维导图全部用standalone文档类单独编译生成单独的 PDF 文件主页文档里用\includegraphics控制显示宽度。这样即使图很大也可以在 standalone 文档中用scale 0.8缩放后再输出。如果图实在太大一张 A4 放不下更推荐把树拆成两棵分别做成总览和子模块详情两张图在正文中配合引用阅读体验比硬塞一整棵树好得多。7. 进阶玩法beamer 逐步呈现、子树批量改色与脚本自动生成7.1 在 beamer 演示中让思维导图逐步展开讲课或演示时一上来展示整张思维导图会让观众不知道该看哪里。用 beamer 可以做到分支逐条出现。最简单的做法不是用复杂的 TikZ 动画而是在每一帧用\only包裹不同版本的森林图\only1{% \begin{forest} [主线 [分支A] [分支B] ] \end{forest} } \only2{% \begin{forest} [主线 [分支A] [分支B [细节1] [细节2]] ] \end{forest} }问题是第二帧比第一帧多出子节点后树的整体宽度会变化画面会轻微跳动。解决办法是在第一帧就放占位节点\only1{% \begin{forest} [主线 [分支A] [分支B [占位] [占位] ] ] \end{forest} }把占位节点用draw none, text none隐藏起来这样两帧的树结构一致坐标完全对齐演示时节点出现就不会跳。等第二帧再把真实内容填进去视觉上就像是在原地平滑展开。7.2 对整个子树批量改色与统一样式前面提过for subtree是给整棵子树改样式的利器。实际场景中经常用这个功能来强调某个模块下的所有内容都属于重点[重点模块, for subtree {draw red!50, fill red!8, text black} [子节点1] [子节点2] [子节点3] ]只要把这个写在某个子节点上方下面的所有后代节点都会继承指定样式。如果还想让根节点也同步变色可以把节点和子节点分别设置但大多数情况下for subtree就够了。7.3 用脚本从 JSON 生成 Forest 代码如果思维导图数据来自数据库、配置文件或前端路由表手写 Forest 代码容易出错。写个几十行的小脚本把 JSON 转成 Forest 嵌套结构效率会高很多。核心逻辑很简单递归拼字符串import json def to_forest(node): name node.get(name, ) children node.get(children, []) if not children: return f[{name}] inner .join(to_forest(child) for child in children) return f[{name} {inner}] with open(tree.json, encodingutf-8) as f: data json.load(f) print(to_forest(data))输出结果就是可以直接贴进.tex文件的 Forest 代码。如果 JSON 里的文字包含 LaTeX 特殊字符记得先做转义把_、、%替换成\_、\、\%等。这个方案我在生成项目任务拆解结构时用得很顺手。最后分享我个人的工作习惯画任何思维导图都先在大纲工具里把层级敲干净再转换成 Forest 代码。后续调整只动s sep、l sep、fork sep这几个数字以及节点文字本身两分钟就能完成一次迭代。如果你也受够了在线脑图工具和 LaTeX 文档之间来回导图的麻烦Forest 就是目前最舒服的解法。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑