1. 项目概述为什么我们需要subfloat在撰写技术报告、学术论文或者任何需要图文并茂的文档时我们常常会遇到一个场景需要将多张相关的图片或子图组合在一起作为一个逻辑上的整体进行展示和引用。比如你可能想展示一个算法的三个不同阶段的输出结果或者对比同一组数据在不同参数下的可视化效果。在 LaTeX 中最基础的图文排版工具是figure环境和\includegraphics命令但它们一次只能处理一张图。如果你简单地将三张图并排放置它们会成为三个独立的浮动体拥有各自的编号如图1图2图3这破坏了它们之间的逻辑关联性引用起来也非常不便。这时subfloat通常通过subfig或subcaption宏包提供就成为了解决这个痛点的利器。它允许你在一个主figure环境内创建多个带有独立子编号如 (a), (b), (c)的子图。你可以为每个子图单独添加简短的标题子标题同时为整个组合图添加一个总标题。在正文中你可以引用整个图如“如图1所示”也可以精确地引用其中的某个子图如“如图1(a)所示”。这不仅使得排版整洁、专业更重要的是它极大地增强了文档的逻辑性和可读性。我见过很多初学者包括早期的我自己会用各种“土办法”来拼凑子图比如用图像处理软件把多张图合成一张或者在 LaTeX 里用minipage手动模拟。前者失去了矢量图的清晰度和后期修改的灵活性后者则无法实现自动的子图编号和引用维护起来是一场噩梦。subfloat正是为了优雅地解决这些问题而生的。接下来我将深入拆解它的使用从宏包选择、基础语法到高级技巧和避坑指南让你能真正掌握这个强大工具。2. 核心工具选型subfigvssubcaption在 LaTeX 中实现子图功能主要有两个流行的宏包subfig和subcaption。选择哪一个是上手第一步就需要明确的。这不仅仅是语法上的细微差别更关系到与文档中其他宏包尤其是caption和hyperref的兼容性以及最终排版效果的精细控制。2.1subfig宏包经典但需谨慎subfig是一个历史悠久的宏包功能稳定且强大。它提供了\subfloat命令这也是本文标题的直接来源。基本用法示例\usepackage{subfig} ... \begin{figure}[htbp] \centering \subfloat[子图A的简短说明]{\includegraphics[width0.45\linewidth]{figA.pdf}\label{fig:subA}} \hfill \subfloat[子图B的简短说明]{\includegraphics[width0.45\linewidth]{figB.pdf}\label{fig:subB}} \caption{这里是整个组合图的总标题。} \label{fig:main} \end{figure}它的优点语法直观\subfloat[...]{...}的结构非常清晰中括号内是子标题大括号内是子图内容。引用灵活可以使用\ref{fig:subA}来引用子图 (a)使用\ref{fig:main}来引用整个图1。列表支持在图表目录中可以配置是否列出子图。然而它有一个显著的缺点兼容性问题。subfig与另一个非常常用的宏包caption用于自定义标题格式存在已知的冲突。同时在与hyperref用于生成超链接配合使用时也可能需要额外的配置才能让子图的引用链接正常工作。对于现代 LaTeX 文档尤其是使用了复杂格式模板的论文这种潜在的冲突会增加不必要的调试成本。注意如果你使用的模板明确要求或已经加载了subfig那么遵循模板即可。但在开始一个新项目时我通常更推荐下面这个更现代的替代品。2.2subcaption宏包现代推荐之选subcaption宏包可以看作是subfig的现代化替代和增强。它被设计为与caption宏包完美兼容并且通常能更好地与hyperref协同工作。它提供了subfigure环境注意是subfigure不是subfloat。基本用法示例\usepackage{caption} \usepackage{subcaption} ... \begin{figure}[htbp] \centering \begin{subfigure}[b]{0.45\linewidth} \centering \includegraphics[width\textwidth]{figA.pdf} \caption{子图A的简短说明} \label{fig:subA} \end{subfigure} \hfill \begin{subfigure}[b]{0.45\linewidth} \centering \includegraphics[width\textwidth]{figB.pdf} \caption{子图B的简短说明} \label{fig:subB} \end{subfigure} \caption{这里是整个组合图的总标题。} \label{fig:main} \end{figure}它的核心优势完美兼容与caption宏包无缝集成你可以使用caption的所有强大功能如字体、间距、悬挂缩进等来统一设置主标题和子标题的样式。环境化语法subfigure是一个完整的环境你可以在其中进行更复杂的排版比如在图片下方再添加一段文字或公式这比\subfloat的单命令形式更灵活。更少的冲突大大降低了与hyperref等其他宏包冲突的概率。实操心得在我近五年的 LaTeX 写作中只要不是维护遗留文档我几乎无一例外地选择subcaption。它的学习曲线和subfig几乎一样平缓但避免了后期可能出现的令人头疼的兼容性问题。特别是当你需要精细调整标题格式时captionsubcaption的组合提供了无与伦比的控制力。因此对于新项目强烈建议从subcaption开始。下文的主要讲解也将基于subcaption宏包。3. 从零开始一个完整的子图排版实例让我们通过一个具体的、可复现的例子来详细拆解使用subcaption排版子图的每一个步骤和细节。假设我们要在一个图里展示三种不同的函数曲线正弦、余弦和正切。3.1 文档前期准备与宏包加载首先你需要一个可编译的 LaTeX 文档基础框架。我推荐使用article文档类因为它简单通用。\documentclass{article} \usepackage{graphicx} % 必须插入图片 \usepackage{caption} % 强烈推荐用于标题样式控制 \usepackage{subcaption} % 核心子图功能 % 可选但推荐的宏包 \usepackage{amsmath} % 提供更好的数学公式支持可能在标题或图中用到 \usepackage{hyperref} % 生成可点击的交叉引用链接需最后加载之一 \usepackage{blindtext} % 仅用于生成示例文本实际写作中不需要 \begin{document} \blindtext % 这是一些占位文本用于查看浮动体位置 % 我们的图形将放在这里 \blindtext % 更多占位文本 \end{document}关键点解析graphicx是插入图片的基石没有它\includegraphics命令无法工作。caption和subcaption通常一起加载。subcaption会自动处理对caption的依赖但显式声明是个好习惯。hyperref宏包必须在绝大多数其他宏包之后加载subcaption的文档特别说明了兼容性通常放在它之后没问题以确保交叉引用能正确生成超链接。一个常见的顺序是把hyperref放在subcaption之后但在\begin{document}之前。图片文件格式LaTeX 原生支持.pdf,.png,.jpg等格式。对于包含文字、线条的图表如函数图、流程图优先使用.pdf或.eps矢量格式它们在任意缩放下都能保持清晰。照片类图片可使用.jpg或.png。3.2 构建包含子图的浮动体环境现在我们在文档正文部分插入我们的图形。我们将创建三个子图每个子图显示一个函数。\begin{figure}[htbp] \centering % 使整个figure环境内容居中 % 第一个子图正弦函数 \begin{subfigure}[b]{0.32\linewidth} \centering % 使子图内容在subfigure的宽度内居中 \includegraphics[width\textwidth]{sine_plot.pdf} \caption{$y \sin(x)$} % 子标题可以使用数学模式 \label{fig:sine} \end{subfigure} \hfill % 充满水平空间使子图之间均匀分布 % 第二个子图余弦函数 \begin{subfigure}[b]{0.32\linewidth} \centering \includegraphics[width\textwidth]{cosine_plot.pdf} \caption{$y \cos(x)$} \label{fig:cosine} \end{subfigure} \hfill % 第三个子图正切函数 \begin{subfigure}[b]{0.32\linewidth} \centering \includegraphics[width\textwidth]{tangent_plot.pdf} \caption{$y \tan(x)$} \label{fig:tangent} \end{subfigure} \caption{三种基本三角函数的曲线图。 (a) 正弦函数具有周期性和奇对称性(b) 余弦函数是正弦函数的相位平移(c) 正切函数在 $\frac{\pi}{2}k\pi$ 处存在渐近线。} % 总标题 \label{fig:trig_functions} % 整个图的标签 \end{figure}代码逐行解读与参数详解\begin{figure}[htbp]开启浮动体环境。[htbp]是位置参数建议保持默认。它告诉 LaTeX 尝试按顺序在此处(h)、页面顶部(t)、页面底部(b)、独立一页(p)放置图形。LaTeX 会最终决定一个最优位置以保证排版美观我们应尊重其算法避免过度使用[h!]等强制命令。\centering这个命令作用于整个figure环境使其包含的所有内容三个subfigure在页面水平方向上居中。\begin{subfigure}[b]{0.32\linewidth}开启一个子图环境。位置参数[b]可选指定子图内内容的垂直对齐方式。b表示底部对齐 (bottom)t表示顶部对齐 (top)c表示居中 (center默认)。当子图高度不一致时这个参数非常有用。例如如果一张是全景照片矮宽一张是人像照片高瘦使用[b]可以让它们的底部对齐看起来更整齐。宽度参数{0.32\linewidth}指定该subfigure环境所占的宽度。\linewidth在当前上下文即figure内通常等于文本宽度。我们计划排三列所以每列宽度略小于 1/3这里取 0.32为中间的\hfill留出一点空隙。\includegraphics[width\textwidth]{sine_plot.pdf}插入图片。width\textwidth这里的\textwidth指的是当前subfigure环境的宽度即我们刚才设置的0.32\linewidth。这个设置意味着图片将撑满子图环境的宽度是实现等宽排列的关键。图片文件名确保sine_plot.pdf等文件存在于你的 LaTeX 项目目录中或者提供正确的相对/绝对路径。\caption{...}和\label{...}为子图添加标题和标签。顺序很重要必须先\caption后\label。\label命令会记录最近一个\caption产生的计数器编号如果顺序反了引用就会出错。\hfill这是一个弹性长度命令意为“尽可能填充空间”。放在两个subfigure环境之间它会将两者推向两端从而在它们之间创造出均匀的间距。这是实现子图水平均匀分布最简洁有效的方法。最后的\caption和\label为整个组合图添加总标题和标签。编译与输出效果编译上述代码使用pdflatex-bibtex如有参考文献-pdflatex-pdflatex完整流程以确保交叉引用正确你将得到一个编号为“图1”的浮动体。其中包含三个并排的子图分别标记为 (a), (b), (c)。子图标题在图片下方总标题在所有子图下方。在文中使用\ref{fig:sine}会得到 “1(a)”使用\ref{fig:trig_functions}会得到 “1”。4. 高级布局与样式自定义掌握了基础排版后我们常常需要应对更复杂的布局需求和样式调整。subcaption配合caption宏包提供了强大的控制能力。4.1 复杂网格布局2x2 3x1等子图不一定总是排成一行。通过组合多个subfigure环境并合理使用换行可以轻松创建网格。示例2x2 网格布局\begin{figure}[htbp] \centering % 第一行 \begin{subfigure}[b]{0.48\linewidth} \centering \includegraphics[width0.9\textwidth]{result_phase1.pdf} \caption{第一阶段结果} \label{fig:p1} \end{subfigure} \hfill \begin{subfigure}[b]{0.48\linewidth} \centering \includegraphics[width0.9\textwidth]{result_phase2.pdf} \caption{第二阶段结果} \label{fig:p2} \end{subfigure} % 手动换行并添加垂直间距 \\[6pt] % 可选增加行间距 % 第二行 \begin{subfigure}[b]{0.48\linewidth} \centering \includegraphics[width0.9\textwidth]{result_phase3.pdf} \caption{第三阶段结果} \label{fig:p3} \end{subfigure} \hfill \begin{subfigure}[b]{0.48\linewidth} \centering \includegraphics[width0.9\textwidth]{result_final.pdf} \caption{最终结果} \label{fig:pf} \end{subfigure} \caption{算法迭代过程的四个阶段输出可视化。} \label{fig:algorithm_stages} \end{figure}要点使用\\[6pt]在两行子图之间插入一个换行并可选地增加[6pt]这样的垂直间距。每行内的子图宽度之和应小于 1这里用 0.480.480.96为\hfill留出空间。子图内的图片宽度设为0.9\textwidth而非\textwidth是为了在子图边框内留出一些边距使排版更透气。4.2 垂直堆叠布局3x1当图片需要纵向比较时垂直排列是更好的选择。\begin{figure}[htbp] \centering \begin{subfigure}[t]{\linewidth} % 宽度占满一行 \centering \includegraphics[width0.6\linewidth]{architecture_overview.pdf} \caption{系统总体架构} \label{fig:arch} \end{subfigure} % 较大的垂直间距 \vspace{1em} \begin{subfigure}[t]{\linewidth} \centering \includegraphics[width0.8\linewidth]{module_detail.pdf} \caption{核心模块详细设计} \label{fig:module} \end{subfigure} \vspace{1em} \begin{subfigure}[t]{\linewidth} \centering \includegraphics[width0.7\linewidth]{data_flow.pdf} \caption{数据处理流程} \label{fig:flow} \end{subfigure} \caption{系统设计的三个层次示意图。} \label{fig:system_design} \end{figure}要点每个subfigure的宽度设为\linewidth使其独占一行。使用\vspace{1em}在子图之间添加可调节的垂直间距。em是相对单位与当前字体大小相关比固定值如10pt更具适应性。子图内图片的宽度如0.6\linewidth可以根据图片本身的内容和重要性灵活调整不必相同。4.3 深度自定义标题样式默认的子图编号格式是“(a)”、“(b)”。有时我们需要改成“a)”、“(A)”或其他样式。同时主标题和子标题的字体、间距也可能需要调整。这需要借助caption和subcaption宏包提供的命令。修改子图编号格式在导言区\begin{document}之前添加以下代码\usepackage{caption} \usepackage{subcaption} \captionsetup[subfigure]{labelformatsimple} % 将标签格式设为“简单”模式 \renewcommand\thesubfigure{\alph{subfigure}} % 默认就是小写字母此命令可改为大写字母 \Alph % 或者改成带点的小写字母 % \renewcommand\thesubfigure{\alph{subfigure}.} % 或者改成罗马数字 % \renewcommand\thesubfigure{\roman{subfigure}}labelformat有几个选项simple: 仅显示编号如a。parens: 编号在括号内如(a)默认。brace: 编号在花括号内如{a}。统一调整所有标题样式\usepackage[fontsmall, labelfontbf, justificationcentering]{caption} \usepackage{subcaption}fontsmall: 标题字体大小设为\small。labelfontbf: 标签如“图 1”使用粗体。justificationcentering: 标题文本居中对齐默认是左对齐。对于很长的标题居中对齐可能不如justificationraggedright右对齐或默认的左对齐美观。单独调整子标题样式\captionsetup[subfigure]{fontfootnotesize, labelfontsc, labelformatparens}fontfootnotesize: 子标题使用更小的字体。labelfontsc: 子图标签如 (a)使用小型大写字母Small Caps字体。这些设置只对subfigure环境生效不会影响主标题。调整标题间距\captionsetup{skip5pt} % 设置标题与上方内容的距离 \captionsetup[subfigure]{skip2pt} % 设置子标题与上方图片的距离skip参数控制的是标题或子标题与其上方内容的距离。这个细微的调整对于整体视觉平衡很重要。实操心得样式一致性优先在一篇文档中所有图形的标题样式字体、编号格式、间距应保持严格一致。我建议在导言区一次性完成所有全局设置。除非有特殊强调的需求否则避免在正文中局部修改样式。一个清晰的、一致的图表编号系统是专业文档的标志。5. 常见问题、排查技巧与避坑指南即使语法正确在实际使用subcaption时你仍可能会遇到一些棘手的问题。下面是我在多年实践中总结的常见“坑”及其解决方案。5.1 引用错误子图引用显示为“??”这是 LaTeX 新手最常遇到的问题。引用\ref{}显示为问号意味着 LaTeX 没有找到对应的标签。原因与排查步骤编译次数不足LaTeX 的交叉引用需要多次编译才能正确解析。标准的流程是pdflatex your_document.tex生成.aux文件记录标签bibtex your_document如果你用了参考文献处理.bib文件pdflatex your_document.tex读入.aux中的引用信息pdflatex your_document.tex再次解析确保所有引用稳定 大多数现代编辑器如 VS Code with LaTeX Workshop, TeXstudio的“编译”按钮会自动执行这个完整流程。如果你手动编译请确保至少运行两次pdflatex。\label放置位置错误\label必须放在\caption命令之后。\label记录的是最近一个计数器如图号、表号、章节号的值。如果先写\label再写\caption那么\label记录的就是上一个计数器导致引用错误。% 错误 \begin{subfigure}{...} \includegraphics{...} \label{fig:wrong} % 此时还没有生成子图编号 \caption{子标题} \end{subfigure} % 正确 \begin{subfigure}{...} \includegraphics{...} \caption{子标题} \label{fig:correct} % 在 \caption 之后 \end{subfigure}标签名冲突确保你在整个文档中使用的\label{}里面的名字是唯一的。不要在图、表、章节、公式中使用相同的标签名。5.2 图片位置“乱跑”或不显示LaTeX 的浮动体figure,table设计初衷是为了避免出现大块空白优化整体排版。因此图形可能不会精确出现在你编写代码的位置。应对策略理解并信任浮动算法除非排版要求极其严格如某些期刊要求图必须紧随文中首次提及处否则最好接受 LaTeX 的安排。在最终稿中位置通常是合理的。使用位置修饰符[htbp]是合理的默认值。你可以尝试[H]需要float宏包它会强制将图形放在代码位置但这极易造成页面底部大片空白不推荐。检查图片尺寸如果图片本身宽度超过了\textwidth或者你在subfigure中设置的宽度总和加上\hfill的空间大于 1图片可能会溢出到页面外导致无法正常放置和显示。始终确保宽度 * 列数 1。查看日志文件如果图片根本不显示编译后查看.log文件。常见错误是“Filexxx.pdfnot found”。检查文件名拼写、大小写在 Linux 系统下区分大小写、文件路径是否正确。使用相对路径时确保文件在 LaTeX 源文件所在目录或其子目录下。5.3 子图标题或编号样式不符合预期如果你按照第4.3节的方法自定义了样式但编译后没变化请检查宏包加载顺序\captionsetup命令必须在加载caption和subcaption宏包之后在\begin{document}之前使用。正文中的设置可能会被局部环境覆盖。作用域冲突如果在文档中某个局部如某个figure环境内或\begin{group}内再次使用了\captionsetup它可能会覆盖全局设置。检查是否有局部修改。模板的威力如果你在使用期刊或学校的 LaTeX 模板模板很可能已经预定义了复杂的标题样式。你的自定义命令可能会被模板中的命令覆盖。在这种情况下最稳妥的方法是查阅模板文档找到它提供的专用命令或选项来修改样式而不是直接使用\captionsetup。5.4 子图间距与对齐的微调水平间距\hfill是自动填充但有时你需要固定间距。可以用\hspace{1cm}替代\hfill来插入固定的1厘米间距。垂直对齐当子图高度不一致时subfigure的[b],[t],[c]选项就派上用场了。通常[b]底部对齐视觉效果最稳定。你可以给一行中所有subfigure加上相同的选项。整体缩放如果你觉得所有子图作为一个整体太小或太大不要逐个修改子图中的\includegraphics的宽度。更优雅的方法是调整figure环境的缩放比例。但这通常不直接支持。更好的做法是在生成图片时如使用 Python 的 Matplotlib 或 MATLAB就设定好合适的图形尺寸和 DPI使得以width\textwidth插入时大小正好。5.5 与hyperref宏包配合的注意事项hyperref宏包让 PDF 中的交叉引用变成可点击的链接体验极佳。与subcaption配合基本是开箱即用。但需注意加载顺序hyperref宏包对加载顺序非常敏感。一个广泛认可的最佳实践是将hyperref放在所有宏包加载命令的最后除了极少数例外如cleveref需要在其后。例如\usepackage{graphicx} \usepackage{caption} \usepackage{subcaption} \usepackage{amsmath} % ... 其他宏包 \usepackage{hyperref} % 几乎放在最后 % \usepackage{cleveref} % 如果使用放在 hyperref 之后链接到子图当正确配置后使用\ref{fig:subA}生成的 “1(a)” 中的 “(a)” 也会是一个可点击的链接直接跳转到对应的子图非常方便。一个终极排查清单当你遇到无法解决的问题时请按此清单核对✅ 编译了足够次数≥2 次pdflatex吗✅\label在\caption后面吗✅ 标签名唯一吗✅ 图片文件存在且路径正确吗✅ 所有宏包都正确加载了吗检查.log文件有无 “Package not found” 错误✅ 图片宽度总和是否超出了可用空间✅ 是否与其他宏包如过时的subfigure冲突确保只加载了subcaption或subfig中的一个。✅ 如果使用模板是否遵循了模板关于图表排版的特殊规定掌握subcaption进行子图排版是 LaTeX 进阶使用的标志性技能之一。它不仅能让你产出外观专业的文档更能通过清晰的结构化编号和引用极大提升文档内容组织的严谨性。从简单的并排到复杂的网格再到细致的样式调整希望这篇详尽的指南能成为你手边的实用参考。记住多实践多编译遇到问题时耐心查看日志文件你很快就能驾驭这个强大的工具。
LaTeX子图排版完全指南:subcaption宏包实战与避坑
1. 项目概述为什么我们需要subfloat在撰写技术报告、学术论文或者任何需要图文并茂的文档时我们常常会遇到一个场景需要将多张相关的图片或子图组合在一起作为一个逻辑上的整体进行展示和引用。比如你可能想展示一个算法的三个不同阶段的输出结果或者对比同一组数据在不同参数下的可视化效果。在 LaTeX 中最基础的图文排版工具是figure环境和\includegraphics命令但它们一次只能处理一张图。如果你简单地将三张图并排放置它们会成为三个独立的浮动体拥有各自的编号如图1图2图3这破坏了它们之间的逻辑关联性引用起来也非常不便。这时subfloat通常通过subfig或subcaption宏包提供就成为了解决这个痛点的利器。它允许你在一个主figure环境内创建多个带有独立子编号如 (a), (b), (c)的子图。你可以为每个子图单独添加简短的标题子标题同时为整个组合图添加一个总标题。在正文中你可以引用整个图如“如图1所示”也可以精确地引用其中的某个子图如“如图1(a)所示”。这不仅使得排版整洁、专业更重要的是它极大地增强了文档的逻辑性和可读性。我见过很多初学者包括早期的我自己会用各种“土办法”来拼凑子图比如用图像处理软件把多张图合成一张或者在 LaTeX 里用minipage手动模拟。前者失去了矢量图的清晰度和后期修改的灵活性后者则无法实现自动的子图编号和引用维护起来是一场噩梦。subfloat正是为了优雅地解决这些问题而生的。接下来我将深入拆解它的使用从宏包选择、基础语法到高级技巧和避坑指南让你能真正掌握这个强大工具。2. 核心工具选型subfigvssubcaption在 LaTeX 中实现子图功能主要有两个流行的宏包subfig和subcaption。选择哪一个是上手第一步就需要明确的。这不仅仅是语法上的细微差别更关系到与文档中其他宏包尤其是caption和hyperref的兼容性以及最终排版效果的精细控制。2.1subfig宏包经典但需谨慎subfig是一个历史悠久的宏包功能稳定且强大。它提供了\subfloat命令这也是本文标题的直接来源。基本用法示例\usepackage{subfig} ... \begin{figure}[htbp] \centering \subfloat[子图A的简短说明]{\includegraphics[width0.45\linewidth]{figA.pdf}\label{fig:subA}} \hfill \subfloat[子图B的简短说明]{\includegraphics[width0.45\linewidth]{figB.pdf}\label{fig:subB}} \caption{这里是整个组合图的总标题。} \label{fig:main} \end{figure}它的优点语法直观\subfloat[...]{...}的结构非常清晰中括号内是子标题大括号内是子图内容。引用灵活可以使用\ref{fig:subA}来引用子图 (a)使用\ref{fig:main}来引用整个图1。列表支持在图表目录中可以配置是否列出子图。然而它有一个显著的缺点兼容性问题。subfig与另一个非常常用的宏包caption用于自定义标题格式存在已知的冲突。同时在与hyperref用于生成超链接配合使用时也可能需要额外的配置才能让子图的引用链接正常工作。对于现代 LaTeX 文档尤其是使用了复杂格式模板的论文这种潜在的冲突会增加不必要的调试成本。注意如果你使用的模板明确要求或已经加载了subfig那么遵循模板即可。但在开始一个新项目时我通常更推荐下面这个更现代的替代品。2.2subcaption宏包现代推荐之选subcaption宏包可以看作是subfig的现代化替代和增强。它被设计为与caption宏包完美兼容并且通常能更好地与hyperref协同工作。它提供了subfigure环境注意是subfigure不是subfloat。基本用法示例\usepackage{caption} \usepackage{subcaption} ... \begin{figure}[htbp] \centering \begin{subfigure}[b]{0.45\linewidth} \centering \includegraphics[width\textwidth]{figA.pdf} \caption{子图A的简短说明} \label{fig:subA} \end{subfigure} \hfill \begin{subfigure}[b]{0.45\linewidth} \centering \includegraphics[width\textwidth]{figB.pdf} \caption{子图B的简短说明} \label{fig:subB} \end{subfigure} \caption{这里是整个组合图的总标题。} \label{fig:main} \end{figure}它的核心优势完美兼容与caption宏包无缝集成你可以使用caption的所有强大功能如字体、间距、悬挂缩进等来统一设置主标题和子标题的样式。环境化语法subfigure是一个完整的环境你可以在其中进行更复杂的排版比如在图片下方再添加一段文字或公式这比\subfloat的单命令形式更灵活。更少的冲突大大降低了与hyperref等其他宏包冲突的概率。实操心得在我近五年的 LaTeX 写作中只要不是维护遗留文档我几乎无一例外地选择subcaption。它的学习曲线和subfig几乎一样平缓但避免了后期可能出现的令人头疼的兼容性问题。特别是当你需要精细调整标题格式时captionsubcaption的组合提供了无与伦比的控制力。因此对于新项目强烈建议从subcaption开始。下文的主要讲解也将基于subcaption宏包。3. 从零开始一个完整的子图排版实例让我们通过一个具体的、可复现的例子来详细拆解使用subcaption排版子图的每一个步骤和细节。假设我们要在一个图里展示三种不同的函数曲线正弦、余弦和正切。3.1 文档前期准备与宏包加载首先你需要一个可编译的 LaTeX 文档基础框架。我推荐使用article文档类因为它简单通用。\documentclass{article} \usepackage{graphicx} % 必须插入图片 \usepackage{caption} % 强烈推荐用于标题样式控制 \usepackage{subcaption} % 核心子图功能 % 可选但推荐的宏包 \usepackage{amsmath} % 提供更好的数学公式支持可能在标题或图中用到 \usepackage{hyperref} % 生成可点击的交叉引用链接需最后加载之一 \usepackage{blindtext} % 仅用于生成示例文本实际写作中不需要 \begin{document} \blindtext % 这是一些占位文本用于查看浮动体位置 % 我们的图形将放在这里 \blindtext % 更多占位文本 \end{document}关键点解析graphicx是插入图片的基石没有它\includegraphics命令无法工作。caption和subcaption通常一起加载。subcaption会自动处理对caption的依赖但显式声明是个好习惯。hyperref宏包必须在绝大多数其他宏包之后加载subcaption的文档特别说明了兼容性通常放在它之后没问题以确保交叉引用能正确生成超链接。一个常见的顺序是把hyperref放在subcaption之后但在\begin{document}之前。图片文件格式LaTeX 原生支持.pdf,.png,.jpg等格式。对于包含文字、线条的图表如函数图、流程图优先使用.pdf或.eps矢量格式它们在任意缩放下都能保持清晰。照片类图片可使用.jpg或.png。3.2 构建包含子图的浮动体环境现在我们在文档正文部分插入我们的图形。我们将创建三个子图每个子图显示一个函数。\begin{figure}[htbp] \centering % 使整个figure环境内容居中 % 第一个子图正弦函数 \begin{subfigure}[b]{0.32\linewidth} \centering % 使子图内容在subfigure的宽度内居中 \includegraphics[width\textwidth]{sine_plot.pdf} \caption{$y \sin(x)$} % 子标题可以使用数学模式 \label{fig:sine} \end{subfigure} \hfill % 充满水平空间使子图之间均匀分布 % 第二个子图余弦函数 \begin{subfigure}[b]{0.32\linewidth} \centering \includegraphics[width\textwidth]{cosine_plot.pdf} \caption{$y \cos(x)$} \label{fig:cosine} \end{subfigure} \hfill % 第三个子图正切函数 \begin{subfigure}[b]{0.32\linewidth} \centering \includegraphics[width\textwidth]{tangent_plot.pdf} \caption{$y \tan(x)$} \label{fig:tangent} \end{subfigure} \caption{三种基本三角函数的曲线图。 (a) 正弦函数具有周期性和奇对称性(b) 余弦函数是正弦函数的相位平移(c) 正切函数在 $\frac{\pi}{2}k\pi$ 处存在渐近线。} % 总标题 \label{fig:trig_functions} % 整个图的标签 \end{figure}代码逐行解读与参数详解\begin{figure}[htbp]开启浮动体环境。[htbp]是位置参数建议保持默认。它告诉 LaTeX 尝试按顺序在此处(h)、页面顶部(t)、页面底部(b)、独立一页(p)放置图形。LaTeX 会最终决定一个最优位置以保证排版美观我们应尊重其算法避免过度使用[h!]等强制命令。\centering这个命令作用于整个figure环境使其包含的所有内容三个subfigure在页面水平方向上居中。\begin{subfigure}[b]{0.32\linewidth}开启一个子图环境。位置参数[b]可选指定子图内内容的垂直对齐方式。b表示底部对齐 (bottom)t表示顶部对齐 (top)c表示居中 (center默认)。当子图高度不一致时这个参数非常有用。例如如果一张是全景照片矮宽一张是人像照片高瘦使用[b]可以让它们的底部对齐看起来更整齐。宽度参数{0.32\linewidth}指定该subfigure环境所占的宽度。\linewidth在当前上下文即figure内通常等于文本宽度。我们计划排三列所以每列宽度略小于 1/3这里取 0.32为中间的\hfill留出一点空隙。\includegraphics[width\textwidth]{sine_plot.pdf}插入图片。width\textwidth这里的\textwidth指的是当前subfigure环境的宽度即我们刚才设置的0.32\linewidth。这个设置意味着图片将撑满子图环境的宽度是实现等宽排列的关键。图片文件名确保sine_plot.pdf等文件存在于你的 LaTeX 项目目录中或者提供正确的相对/绝对路径。\caption{...}和\label{...}为子图添加标题和标签。顺序很重要必须先\caption后\label。\label命令会记录最近一个\caption产生的计数器编号如果顺序反了引用就会出错。\hfill这是一个弹性长度命令意为“尽可能填充空间”。放在两个subfigure环境之间它会将两者推向两端从而在它们之间创造出均匀的间距。这是实现子图水平均匀分布最简洁有效的方法。最后的\caption和\label为整个组合图添加总标题和标签。编译与输出效果编译上述代码使用pdflatex-bibtex如有参考文献-pdflatex-pdflatex完整流程以确保交叉引用正确你将得到一个编号为“图1”的浮动体。其中包含三个并排的子图分别标记为 (a), (b), (c)。子图标题在图片下方总标题在所有子图下方。在文中使用\ref{fig:sine}会得到 “1(a)”使用\ref{fig:trig_functions}会得到 “1”。4. 高级布局与样式自定义掌握了基础排版后我们常常需要应对更复杂的布局需求和样式调整。subcaption配合caption宏包提供了强大的控制能力。4.1 复杂网格布局2x2 3x1等子图不一定总是排成一行。通过组合多个subfigure环境并合理使用换行可以轻松创建网格。示例2x2 网格布局\begin{figure}[htbp] \centering % 第一行 \begin{subfigure}[b]{0.48\linewidth} \centering \includegraphics[width0.9\textwidth]{result_phase1.pdf} \caption{第一阶段结果} \label{fig:p1} \end{subfigure} \hfill \begin{subfigure}[b]{0.48\linewidth} \centering \includegraphics[width0.9\textwidth]{result_phase2.pdf} \caption{第二阶段结果} \label{fig:p2} \end{subfigure} % 手动换行并添加垂直间距 \\[6pt] % 可选增加行间距 % 第二行 \begin{subfigure}[b]{0.48\linewidth} \centering \includegraphics[width0.9\textwidth]{result_phase3.pdf} \caption{第三阶段结果} \label{fig:p3} \end{subfigure} \hfill \begin{subfigure}[b]{0.48\linewidth} \centering \includegraphics[width0.9\textwidth]{result_final.pdf} \caption{最终结果} \label{fig:pf} \end{subfigure} \caption{算法迭代过程的四个阶段输出可视化。} \label{fig:algorithm_stages} \end{figure}要点使用\\[6pt]在两行子图之间插入一个换行并可选地增加[6pt]这样的垂直间距。每行内的子图宽度之和应小于 1这里用 0.480.480.96为\hfill留出空间。子图内的图片宽度设为0.9\textwidth而非\textwidth是为了在子图边框内留出一些边距使排版更透气。4.2 垂直堆叠布局3x1当图片需要纵向比较时垂直排列是更好的选择。\begin{figure}[htbp] \centering \begin{subfigure}[t]{\linewidth} % 宽度占满一行 \centering \includegraphics[width0.6\linewidth]{architecture_overview.pdf} \caption{系统总体架构} \label{fig:arch} \end{subfigure} % 较大的垂直间距 \vspace{1em} \begin{subfigure}[t]{\linewidth} \centering \includegraphics[width0.8\linewidth]{module_detail.pdf} \caption{核心模块详细设计} \label{fig:module} \end{subfigure} \vspace{1em} \begin{subfigure}[t]{\linewidth} \centering \includegraphics[width0.7\linewidth]{data_flow.pdf} \caption{数据处理流程} \label{fig:flow} \end{subfigure} \caption{系统设计的三个层次示意图。} \label{fig:system_design} \end{figure}要点每个subfigure的宽度设为\linewidth使其独占一行。使用\vspace{1em}在子图之间添加可调节的垂直间距。em是相对单位与当前字体大小相关比固定值如10pt更具适应性。子图内图片的宽度如0.6\linewidth可以根据图片本身的内容和重要性灵活调整不必相同。4.3 深度自定义标题样式默认的子图编号格式是“(a)”、“(b)”。有时我们需要改成“a)”、“(A)”或其他样式。同时主标题和子标题的字体、间距也可能需要调整。这需要借助caption和subcaption宏包提供的命令。修改子图编号格式在导言区\begin{document}之前添加以下代码\usepackage{caption} \usepackage{subcaption} \captionsetup[subfigure]{labelformatsimple} % 将标签格式设为“简单”模式 \renewcommand\thesubfigure{\alph{subfigure}} % 默认就是小写字母此命令可改为大写字母 \Alph % 或者改成带点的小写字母 % \renewcommand\thesubfigure{\alph{subfigure}.} % 或者改成罗马数字 % \renewcommand\thesubfigure{\roman{subfigure}}labelformat有几个选项simple: 仅显示编号如a。parens: 编号在括号内如(a)默认。brace: 编号在花括号内如{a}。统一调整所有标题样式\usepackage[fontsmall, labelfontbf, justificationcentering]{caption} \usepackage{subcaption}fontsmall: 标题字体大小设为\small。labelfontbf: 标签如“图 1”使用粗体。justificationcentering: 标题文本居中对齐默认是左对齐。对于很长的标题居中对齐可能不如justificationraggedright右对齐或默认的左对齐美观。单独调整子标题样式\captionsetup[subfigure]{fontfootnotesize, labelfontsc, labelformatparens}fontfootnotesize: 子标题使用更小的字体。labelfontsc: 子图标签如 (a)使用小型大写字母Small Caps字体。这些设置只对subfigure环境生效不会影响主标题。调整标题间距\captionsetup{skip5pt} % 设置标题与上方内容的距离 \captionsetup[subfigure]{skip2pt} % 设置子标题与上方图片的距离skip参数控制的是标题或子标题与其上方内容的距离。这个细微的调整对于整体视觉平衡很重要。实操心得样式一致性优先在一篇文档中所有图形的标题样式字体、编号格式、间距应保持严格一致。我建议在导言区一次性完成所有全局设置。除非有特殊强调的需求否则避免在正文中局部修改样式。一个清晰的、一致的图表编号系统是专业文档的标志。5. 常见问题、排查技巧与避坑指南即使语法正确在实际使用subcaption时你仍可能会遇到一些棘手的问题。下面是我在多年实践中总结的常见“坑”及其解决方案。5.1 引用错误子图引用显示为“??”这是 LaTeX 新手最常遇到的问题。引用\ref{}显示为问号意味着 LaTeX 没有找到对应的标签。原因与排查步骤编译次数不足LaTeX 的交叉引用需要多次编译才能正确解析。标准的流程是pdflatex your_document.tex生成.aux文件记录标签bibtex your_document如果你用了参考文献处理.bib文件pdflatex your_document.tex读入.aux中的引用信息pdflatex your_document.tex再次解析确保所有引用稳定 大多数现代编辑器如 VS Code with LaTeX Workshop, TeXstudio的“编译”按钮会自动执行这个完整流程。如果你手动编译请确保至少运行两次pdflatex。\label放置位置错误\label必须放在\caption命令之后。\label记录的是最近一个计数器如图号、表号、章节号的值。如果先写\label再写\caption那么\label记录的就是上一个计数器导致引用错误。% 错误 \begin{subfigure}{...} \includegraphics{...} \label{fig:wrong} % 此时还没有生成子图编号 \caption{子标题} \end{subfigure} % 正确 \begin{subfigure}{...} \includegraphics{...} \caption{子标题} \label{fig:correct} % 在 \caption 之后 \end{subfigure}标签名冲突确保你在整个文档中使用的\label{}里面的名字是唯一的。不要在图、表、章节、公式中使用相同的标签名。5.2 图片位置“乱跑”或不显示LaTeX 的浮动体figure,table设计初衷是为了避免出现大块空白优化整体排版。因此图形可能不会精确出现在你编写代码的位置。应对策略理解并信任浮动算法除非排版要求极其严格如某些期刊要求图必须紧随文中首次提及处否则最好接受 LaTeX 的安排。在最终稿中位置通常是合理的。使用位置修饰符[htbp]是合理的默认值。你可以尝试[H]需要float宏包它会强制将图形放在代码位置但这极易造成页面底部大片空白不推荐。检查图片尺寸如果图片本身宽度超过了\textwidth或者你在subfigure中设置的宽度总和加上\hfill的空间大于 1图片可能会溢出到页面外导致无法正常放置和显示。始终确保宽度 * 列数 1。查看日志文件如果图片根本不显示编译后查看.log文件。常见错误是“Filexxx.pdfnot found”。检查文件名拼写、大小写在 Linux 系统下区分大小写、文件路径是否正确。使用相对路径时确保文件在 LaTeX 源文件所在目录或其子目录下。5.3 子图标题或编号样式不符合预期如果你按照第4.3节的方法自定义了样式但编译后没变化请检查宏包加载顺序\captionsetup命令必须在加载caption和subcaption宏包之后在\begin{document}之前使用。正文中的设置可能会被局部环境覆盖。作用域冲突如果在文档中某个局部如某个figure环境内或\begin{group}内再次使用了\captionsetup它可能会覆盖全局设置。检查是否有局部修改。模板的威力如果你在使用期刊或学校的 LaTeX 模板模板很可能已经预定义了复杂的标题样式。你的自定义命令可能会被模板中的命令覆盖。在这种情况下最稳妥的方法是查阅模板文档找到它提供的专用命令或选项来修改样式而不是直接使用\captionsetup。5.4 子图间距与对齐的微调水平间距\hfill是自动填充但有时你需要固定间距。可以用\hspace{1cm}替代\hfill来插入固定的1厘米间距。垂直对齐当子图高度不一致时subfigure的[b],[t],[c]选项就派上用场了。通常[b]底部对齐视觉效果最稳定。你可以给一行中所有subfigure加上相同的选项。整体缩放如果你觉得所有子图作为一个整体太小或太大不要逐个修改子图中的\includegraphics的宽度。更优雅的方法是调整figure环境的缩放比例。但这通常不直接支持。更好的做法是在生成图片时如使用 Python 的 Matplotlib 或 MATLAB就设定好合适的图形尺寸和 DPI使得以width\textwidth插入时大小正好。5.5 与hyperref宏包配合的注意事项hyperref宏包让 PDF 中的交叉引用变成可点击的链接体验极佳。与subcaption配合基本是开箱即用。但需注意加载顺序hyperref宏包对加载顺序非常敏感。一个广泛认可的最佳实践是将hyperref放在所有宏包加载命令的最后除了极少数例外如cleveref需要在其后。例如\usepackage{graphicx} \usepackage{caption} \usepackage{subcaption} \usepackage{amsmath} % ... 其他宏包 \usepackage{hyperref} % 几乎放在最后 % \usepackage{cleveref} % 如果使用放在 hyperref 之后链接到子图当正确配置后使用\ref{fig:subA}生成的 “1(a)” 中的 “(a)” 也会是一个可点击的链接直接跳转到对应的子图非常方便。一个终极排查清单当你遇到无法解决的问题时请按此清单核对✅ 编译了足够次数≥2 次pdflatex吗✅\label在\caption后面吗✅ 标签名唯一吗✅ 图片文件存在且路径正确吗✅ 所有宏包都正确加载了吗检查.log文件有无 “Package not found” 错误✅ 图片宽度总和是否超出了可用空间✅ 是否与其他宏包如过时的subfigure冲突确保只加载了subcaption或subfig中的一个。✅ 如果使用模板是否遵循了模板关于图表排版的特殊规定掌握subcaption进行子图排版是 LaTeX 进阶使用的标志性技能之一。它不仅能让你产出外观专业的文档更能通过清晰的结构化编号和引用极大提升文档内容组织的严谨性。从简单的并排到复杂的网格再到细致的样式调整希望这篇详尽的指南能成为你手边的实用参考。记住多实践多编译遇到问题时耐心查看日志文件你很快就能驾驭这个强大的工具。