LaTeX多图排版指南:subcaption与minipage实现专业子图与并列图

发布时间:2026/8/1 4:25:53
LaTeX多图排版指南:subcaption与minipage实现专业子图与并列图 1. 从“一张图不够用”说起为什么需要子图与并列图在撰写学术论文、技术报告或者准备演示文稿时我们经常会遇到一个非常具体且普遍的需求如何将多张相关的图片以清晰、专业且美观的方式组织在同一张图里比如你可能需要展示一个算法的不同阶段输出对比几种方法的实验结果或者从不同角度呈现同一个数据对象。这时候如果粗暴地把几张图直接堆在文档里不仅排版混乱而且会占用大量篇幅让读者难以抓住重点。LaTeX作为学术界和工程界文档排版的“金标准”其强大的图表处理能力正是为了解决这类问题而生。subfigure、subcaption、subfig等宏包以及minipage环境为我们提供了构建“子图”和“并列图”的利器。简单来说子图允许你在一个figure环境内创建多个独立的、可分别添加标题的图片单元而并列图则更侧重于将多张图片在水平或垂直方向上整齐排列共享一个总标题。我见过太多初学者包括当年的我自己面对这个需求时要么用Word笨拙地手动对齐要么在LaTeX里用一堆\includegraphics命令胡乱摆放结果生成的PDF惨不忍睹编号错乱引用困难。其实只要掌握几个核心宏包和正确的语法结构在LaTeX中创建专业级的子图和并列图比想象中简单得多。这篇文章我将结合自己多年撰写论文和报告的经验手把手带你从环境配置、宏包选择到具体语法、高级调整彻底搞定LaTeX中的多图排版。2. 核心武器库选择适合你的宏包与环境在LaTeX中实现子图历史上主要有三大流派古老的subfigure、一度流行的subfig以及目前官方推荐且维护良好的subcaption。对于新项目我的建议非常明确直接使用subcaption宏包。它完美兼容caption宏包语法清晰功能强大并且与hyperref等常用宏包配合良好避免了subfig可能带来的兼容性问题。首先你需要在文档的导言区\begin{document}之前引入必要的宏包\usepackage{graphicx} % 用于插入图片这是基础 \usepackage{subcaption} % 用于创建子图和子标题这是核心 \captionsetup{compatibilityfalse} % 确保与某些文档类的最佳兼容性通常建议加上graphicx是插入任何图片的前提它提供了\includegraphics命令。subcaption则提供了subfigure环境注意在subcaption宏包中它实际是一个环境而非古老的\subfigure命令。除了subcaption另一个常用于实现并列效果的工具是minipage环境。它更像是一个通用的“小页面”容器不仅可以放图片还可以放文本、表格等。将多个minipage并排就能实现图片的并列。它不提供自动的子图编号和标签管理但控制自由度更高。通常subcaption用于需要独立编号和引用的标准子图而minipage用于对排版有特殊定制需求的简单并列。3. 标准操作流程使用subcaption创建规范子图让我们从一个最经典、最常用的场景开始在一个图环境中并排展示两张图每张图都有自己的子标题如(a)和(b)并且整个组合图有一个总标题。3.1 基础并列子图假设我们有两张图片result_a.png和result_b.png宽度都是0.45倍的文本宽度\textwidth并且希望在它们之间留一点空隙。代码如下\begin{figure}[htbp] \centering % 让整个figure环境居中 \begin{subfigure}[b]{0.45\textwidth} \centering \includegraphics[width\linewidth]{result_a.png} \caption{算法在数据集A上的收敛曲线。} \label{fig:sub_a} \end{subfigure} \hfill % 这个命令会在两个子图之间插入弹性空白实现左右撑开 \begin{subfigure}[b]{0.45\textwidth} \centering \includegraphics[width\linewidth]{result_b.png} \caption{算法在数据集B上的收敛曲线。} \label{fig:sub_b} \end{subfigure} \caption{本文提出的XX算法在两个不同数据集上的性能表现对比。} \label{fig:results} \end{figure}逐行解析与关键点\begin{figure}[htbp]: 这是LaTeX的浮动体环境。[htbp]是位置参数告诉LaTeX尽量将图放在此处h、页面顶部t、页面底部b或单独一页p。这是处理图表排版的常规做法防止图片出现在奇怪的位置。\centering: 使整个figure环境的内容居中。\begin{subfigure}[b]{0.45\textwidth}: 开始一个子图环境。[b]是对齐选项这是非常关键但常被忽略的一点。b代表底部对齐bottomt代表顶部对齐topc代表居中center。当你的子图高度不一致时这个选项决定了它们以哪条边为基准对齐。通常我们希望多张图的底部对齐这样看起来更整齐所以常用[b]。如果你希望所有子图的顶部对齐就用[t]。{0.45\textwidth}指定了这个子图环境的宽度。\linewidth在这个环境内会自动继承这个宽度所以\includegraphics[width\linewidth]会让图片恰好撑满子图环境的宽度。\caption和\label: 子图环境内的\caption会生成如“(a)”这样的子标题。\label必须放在\caption之后这样才能正确关联到生成的编号方便后续用\ref{fig:sub_a}来引用。\hfill: 这是一个“弹性填充”命令。它会在两个subfigure环境之间插入尽可能多的空白从而将两者推向容器的左右两端。如果去掉\hfill两个子图会紧挨在一起。你也可以用固定的空白如\hspace{1cm}来精确控制间距。最后的\caption和\label属于整个figure环境生成总标题“图1”和总标签。编译后效果你会得到类似“图1. 本文提出的...对比。(a) 算法在数据集A... (b) 算法在数据集B...”的输出。在文中你可以用\ref{fig:results}引用整个图1用\ref{fig:sub_a}和\ref{fig:sub_b}分别引用子图(a)和(b)。3.2 多行多列复杂布局如果需要布置2x2甚至更复杂的网格原理是一样的只需要在适当的位置换行即可。LaTeX中换行可以用空行两个回车但更清晰的方式是使用\\命令。不过在figure环境中直接使用\\有时会引发问题更推荐用空行或者使用\par。\begin{figure}[htbp] \centering % 第一行 \begin{subfigure}[b]{0.32\textwidth} \centering \includegraphics[width\linewidth]{view_front.png} \caption{前视图} \label{fig:grid_a} \end{subfigure} \hfill \begin{subfigure}[b]{0.32\textwidth} \centering \includegraphics[width\linewidth]{view_side.png} \caption{侧视图} \label{fig:grid_b} \end{subfigure} \hfill \begin{subfigure}[b]{0.32\textwidth} \centering \includegraphics[width\linewidth]{view_top.png} \caption{俯视图} \label{fig:grid_c} \end{subfigure} % 这里用一个空行或 \vspace{0.5cm} 来增加行间距 \vspace{0.5cm} % 第二行 \begin{subfigure}[b]{0.48\textwidth} \centering \includegraphics[width\linewidth]{heatmap_1.png} \caption{工况一温度场} \label{fig:grid_d} \end{subfigure} \hfill \begin{subfigure}[b]{0.48\textwidth} \centering \includegraphics[width\linewidth]{heatmap_2.png} \caption{工况二温度场} \label{fig:grid_e} \end{subfigure} \caption{三维模型的多视角展示与不同工况下的仿真结果。} \label{fig:view_grid} \end{figure}关键技巧宽度计算对于一行N个等宽子图每个子图的宽度可以设为(1.0\textwidth - (N-1)*\fillwidth) / N其中\fillwidth是\hfill产生的弹性间距。为了方便通常直接给一个略小于1/N的固定值比如一行三个就给0.32\textwidth留出间隙空间。行间距控制使用\vspace{长度}在两行之间插入垂直间距。长度单位可以是cm,mm,pt,em等。\vspace{0.5cm}是一个常用的值。混合宽度如示例中第二行两个子图可以占据不同的宽度0.48和0.48只要它们的总宽度加上中间的\hfill不超过一行即可。4. 灵活布局方案使用minipage实现自由并列minipage环境不直接提供子图编号但它给了你最大的控制权。当你不需要自动的“(a)”、“(b)”编号或者需要对并列的内容可能不全是图片进行更复杂的排版时minipage是更好的选择。4.1 基本等宽并列\begin{figure}[htbp] \centering \begin{minipage}[b]{0.45\textwidth} \centering \includegraphics[width0.9\linewidth]{arch_old.png} \captionof{figure}{传统系统架构示意图。} % 注意这里用了 \captionof \label{fig:mp_old} \end{minipage} \hfill \begin{minipage}[b]{0.45\textwidth} \centering \includegraphics[width0.9\linewidth]{arch_new.png} \captionof{figure}{本文提出的新型架构示意图。} \label{fig:mp_new} \end{minipage} % 这里没有总的 \caption因为每个minipage已经用自己的\captionof生成了独立标题。 \end{figure}与subfigure的核心区别编号系统minipage内的\caption命令会失效因为它不知道自己在哪个浮动体里。必须使用\captionof{浮动体类型}{标题内容}命令由caption或subcaption宏包提供。\captionof{figure}会生成一个普通的图标题和编号但它是独立的与外部figure环境无关。这意味着这两个图会被编号为“图1”和“图2”而不是“图1(a)”和“图1(b)”。引用\label需要紧跟在对应的\captionof之后。引用时\ref{fig:mp_old}得到的是“1”\ref{fig:mp_new}得到的是“2”。适用场景当你希望两张图在位置上紧密并列但在编号和引用上完全独立时就用minipage。它生成的更像是两个独立的图被“物理上”放在了一起。4.2 不等宽混合内容并列minipage的强大之处在于可以容纳任意内容。\begin{figure}[htbp] \centering \begin{minipage}[t]{0.65\textwidth} % [t] 顶部对齐 \centering \includegraphics[width\linewidth]{complex_chart.pdf} \end{minipage} \hspace{0.05\textwidth} % 固定间距 \begin{minipage}[t]{0.25\textwidth} \textbf{图例说明}\\ \rule{1em}{1em} 红色曲线模型预测值\\ \rule{1em}{1em} 蓝色散点实验观测值\\ \rule{1em}{1em} 灰色区域95\%置信区间\\ \vspace{5pt} \small 注数据来源于2023年度实验。 \end{minipage} \caption{模型预测与实验数据的对比验证右侧附详细图例。} \label{fig:mix_minipage} \end{figure}这个例子展示了如何将一张宽图和一个文字图例说明并列。右侧的minipage里没有图片只有文本。通过调整两个minipage的宽度比例0.65和0.25和中间的\hspace可以精确控制布局。[t]对齐选项确保了图片的顶部和文字块的顶部对齐。5. 深度定制与常见问题排坑指南掌握了基本语法后要让子图看起来真正专业还需要处理一些细节问题。以下是我在无数次投稿和修改中积累的经验。5.1 子图标题的格式定制默认的子标题格式是“小写字母加括号”如“(a)”。但有些期刊或会议要求使用“a.”、“(A)”甚至“图1a”的格式。subcaption宏包提供了强大的定制能力。在导言区使用\captionsetup命令进行全局设置或在subfigure环境内部进行局部设置。\usepackage{subcaption} % 全局设置将子标题格式改为“字母加点”如“a.” \captionsetup[sub]{labelformatsimple, labelsepperiod} % 或者改为“大写字母加括号”如“(A)” \captionsetup[sub]{labelformatparens, labelsepspace, fontbf}labelformat: 可选simple(a),parens(a),brace{a}等。labelsep: 标签和标题文本之间的分隔符如period(.),space(空格),colon(:),none(无)。font: 标签的字体如bf(粗体),it(斜体),sc(小型大写字母)。如果只想修改某一个子图的格式可以在其内部使用\begin{subfigure}[b]{0.45\textwidth} \centering \includegraphics[width\linewidth]{pic.png} \captionsetup{labelformatbrace} % 局部设置仅影响当前子标题 \caption{使用花括号的标签\{a\}} \label{fig:custom_sub} \end{subfigure}5.2 子图间距与对齐的微调水平间距如前所述\hfill是弹性填充。如果你觉得子图之间距离太大或太小可以用固定值\hspace{长度}替代例如\hspace{0.02\textwidth}。更精细的控制可以结合使用\hfill和固定空格。垂直对齐子图环境[b]、[t]、[c]的对齐基准是整个子图环境的盒子包括图片和其下方的标题。如果图片高度差异很大即使都设置[b]底部对齐也可能因为标题行数不同而导致图片底部并未对齐。此时更根本的解决方法是统一图片的高度。% 在\includegraphics中统一高度宽度自动缩放 \includegraphics[height5cm]{tall_image.jpg} \includegraphics[height5cm]{wide_image.jpg}或者使用adjustbox宏包需引入\usepackage{adjustbox}进行更强大的裁剪和对齐操作。总标题与子图间距默认情况下总标题\caption与上方内容的距离是LaTeX预设的。如果你觉得太近或太远可以在总标题前使用\vspace{长度}来增加空白例如\vspace{10pt}。5.3 引用与交叉引用中的大坑这是最容易出错的地方务必注意\label的位置\label命令必须紧跟在\caption或\captionof命令之后。因为\label记录的是最近一个计数器如图号、表号、章节号的值。如果放在\caption前面\label记录的就是上一个图的编号会导致引用错误。% 正确 \caption{总标题。}\label{fig:total} % 正确 \caption{子标题。}\label{fig:sub1} % 错误\label在\caption前面 \label{fig:wrong}\caption{标题}多次编译当你新增、删除或移动了图、表、章节并修改了\label时LaTeX的交叉引用编号可能不会立即更新。通常需要连续编译两次或使用编译器的“编译-查看PDF”循环功能才能让所有引用\ref{}显示正确的数字。子图引用样式默认情况下\ref{fig:sub_a}只会显示子图编号如“a”。如果你希望引用时显示为“图1a”可以使用\subref{fig:sub_a}命令由subcaption宏包提供。\subref会自动加上父图的编号。在文中写作“如图\subref{fig:sub_a}所示”效果就是“如图1a所示”。5.4 图片路径与格式的最佳实践使用\graphicspath如果你的图片都放在一个子目录如./figures/下每次写路径很麻烦。可以在导言区设置\graphicspath{{figures/}{images/}} % 可以设置多个路径之后\includegraphics命令就可以直接用文件名{result_a.png}LaTeX会自动在指定的路径中查找。优先使用矢量图对于曲线图、示意图尽量生成PDF、EPS或SVG格式。这些是矢量格式无限放大不失真打印效果极佳。graphicx宏包完美支持PDF。对于照片等位图PNG格式支持透明和JPG格式是常见选择。控制图片质量在\includegraphics中除了width和height还可以用scale进行整体缩放用angle进行旋转。但注意过度放大位图会导致模糊。6. 实战案例一篇论文中的多图排版综合演练让我们模拟一个真实的论文场景将前面所有的知识点串联起来。假设我们需要在“实验部分”展示三组结果对比实验2x2的网格对比我们方法Ours和基线方法Baseline在两个指标上的表现。消融实验三个变体模型的效果并列展示。可视化结果一张大图旁边放置文字分析。案例一2x2对比网格\begin{figure}[htbp] \centering \captionsetup[sub]{labelformatparens} % 为这个图的所有子图设置格式为括号 % 第一行指标A \begin{subfigure}[b]{0.48\textwidth} \centering \includegraphics[width0.95\linewidth]{metricA_ours.pdf} \caption{本文方法 (指标A)} \label{fig:exp1_a_ours} \end{subfigure} \hfill \begin{subfigure}[b]{0.48\textwidth} \centering \includegraphics[width0.95\linewidth]{metricA_base.pdf} \caption{基线方法 (指标A)} \label{fig:exp1_a_base} \end{subfigure} \vspace{0.8em} % 行间距稍小一点 % 第二行指标B \begin{subfigure}[b]{0.48\textwidth} \centering \includegraphics[width0.95\linewidth]{metricB_ours.pdf} \caption{本文方法 (指标B)} \label{fig:exp1_b_ours} \end{subfigure} \hfill \begin{subfigure}[b]{0.48\textwidth} \centering \includegraphics[width0.95\linewidth]{metricB_base.pdf} \caption{基线方法 (指标B)} \label{fig:exp1_b_base} \end{subfigure} \caption{与基线方法的定量对比结果。在指标A和指标B上本文方法均表现出显著优势。} \label{fig:comparison} \end{figure}写作技巧在正文中引用时可以写“如图\ref{fig:comparison}所示我们的方法在两项关键指标上均优于基线。具体来看在指标A上图\subref{fig:exp1_a_ours}我们的方法误差降低了约15%而在指标B上图\subref{fig:exp1_b_ours}提升更为明显。”案例二水平排列的消融实验\begin{figure}[htbp] \centering \begin{subfigure}[t]{0.32\textwidth} % 使用[t]顶部对齐因为标题可能行数不同 \centering \includegraphics[height4.5cm]{ablation_full.pdf} \caption{完整模型} \label{fig:abl_full} \end{subfigure} \hfill \begin{subfigure}[t]{0.32\textwidth} \centering \includegraphics[height4.5cm]{ablation_no_attn.pdf} \caption{移除注意力模块} \label{fig:abl_no_attn} \end{subfigure} \hfill \begin{subfigure}[t]{0.32\textwidth} \centering \includegraphics[height4.5cm]{ablation_no_reg.pdf} \caption{移除正则化项} \label{fig:abl_no_reg} \end{subfigure} \caption{消融实验结果。移除任一核心组件均会导致性能下降验证了模型设计的有效性。} \label{fig:ablation} \end{figure}关键点这里统一了图片的height确保了视觉上的高度一致。使用[t]对齐让标题的顶部对齐看起来更整齐。案例三图文混排的深度分析\begin{figure}[htbp] \centering \begin{minipage}[c]{0.7\textwidth} % [c] 垂直居中 \centering \includegraphics[width\linewidth]{feature_visualization.png} \end{minipage} \hspace{0.03\textwidth} \begin{minipage}[c]{0.25\textwidth} \small % 使用小号字体 \textbf{关键区域解读}\\ \textbf{A区高亮}模型成功捕捉到的目标特征区域与先验知识吻合。\\ \textbf{B区阴影}存在少量噪声响应可能源于背景干扰。\\ \textbf{C区框选}未预期的高响应需在后续工作中进一步分析其成因。\\ \vspace{5pt} \textit{颜色映射}红色表示高激活值蓝色表示低激活值。 \end{minipage} \caption{模型内部特征可视化图及其详细解读。右栏文字对图中关键区域进行了说明。} \label{fig:vis_analysis} \end{figure}设计思路当图本身信息量大需要配以较多文字解释时采用minipage并列是清晰的做法。右侧文字栏使用\small缩小字体避免喧宾夺主。[c]垂直居中让图片和文字块在垂直方向上看起来更协调。7. 高级技巧与效率工具当你需要处理大量图片或进行复杂排版时以下技巧能极大提升效率。7.1 循环插入多张子图如果你有一系列命名规则相同的图片如fig1.png,fig2.png, ...,fig9.png并且希望快速生成一个3x3的网格手动写9个subfigure环境非常繁琐。此时可以借助\foreach命令需要pgffor或tikz宏包。\usepackage{pgffor, graphicx, subcaption} \begin{figure}[htbp] \centering \newcounter{subfigcnt} % 定义一个计数器 \setcounter{subfigcnt}{0} \foreach \i in {1,2,...,9} { \stepcounter{subfigcnt} % 计数器加1 \begin{subfigure}[b]{0.3\textwidth} \centering \includegraphics[width\linewidth]{fig\i.png} \caption{实验场景\alph{subfigcnt}} % 使用\alph将计数器转为字母 \label{fig:batch_\i} \end{subfigure} \ifnum\i3 \par \vspace{0.5cm} \fi % 第3张图后换行 \ifnum\i6 \par \vspace{0.5cm} \fi % 第6张图后换行 } \caption{九种不同实验场景下的结果汇总。} \label{fig:batch_all} \end{figure}这个例子展示了如何用循环批量生成子图并自动添加字母编号。\ifnum...\fi条件语句用于在每3张图后换行并添加间距。7.2 与tabular环境结合实现矩阵式排列对于需要严格对齐的复杂布局可以将subfigure或minipage放入tabular表格环境中利用表格单元格来控制对齐和间距。\begin{figure}[htbp] \centering \begin{tabular}{ccc} % 三列都居中 % 第一行 \begin{subfigure}[b]{0.3\textwidth} \centering \includegraphics[width\linewidth]{cell11.jpg} \caption{输入} \label{fig:tab_11} \end{subfigure} \begin{subfigure}[b]{0.3\textwidth} \centering \includegraphics[width\linewidth]{cell12.jpg} \caption{中间结果} \label{fig:tab_12} \end{subfigure} \begin{subfigure}[b]{0.3\textwidth} \centering \includegraphics[width\linewidth]{cell13.jpg} \caption{输出} \label{fig:tab_13} \end{subfigure} \\[0.5cm] % 换行并增加行距 % 第二行 \begin{subfigure}[b]{0.3\textwidth} \centering \includegraphics[width\linewidth]{cell21.jpg} \caption{通道A} \label{fig:tab_21} \end{subfigure} \begin{subfigure}[b]{0.3\textwidth} \centering \includegraphics[width\linewidth]{cell22.jpg} \caption{通道B} \label{fig:tab_22} \end{subfigure} \begin{subfigure}[b]{0.3\textwidth} \centering \includegraphics[width\linewidth]{cell23.jpg} \caption{通道C} \label{fig:tab_23} \end{subfigure} \end{tabular} \caption{使用tabular环境实现的矩阵式图片布局对齐更为精确。} \label{fig:tabular_layout} \end{figure}使用tabular的好处是列间距由\tabcolsep控制非常均匀并且可以通过\\[长度]方便地控制行间距。缺点是代码结构稍显复杂。7.3 利用外部脚本预处理图片在将图片插入LaTeX前做好预处理可以省去很多排版时的麻烦。我常用的方法是使用Python的PIL/Pillow库或ImageMagick命令行工具进行批处理统一尺寸将所有图片裁剪或缩放到相同的宽度或高度。添加边框/白边对于尺寸不一的图片添加统一宽度的白色边框使其在LaTeX中看起来大小一致。格式转换将各种来源的图片统一转换为PDF或PNG格式。一个简单的ImageMagick命令示例将目录下所有JPG图片调整为宽度800像素高度按比例缩放并添加10像素白色边框for img in *.jpg; do convert $img -resize 800x -bordercolor white -border 10x10 processed_$img; done在LaTeX中直接使用处理后的processed_*.jpg排版会轻松很多。8. 环境配置与工作流建议工欲善其事必先利其器。一个流畅的LaTeX写作环境能让你更专注于内容。编辑器选择VS Code LaTeX Workshop插件这是目前最强大的免费组合之一。它提供语法高亮、代码补全、实时预览、错误提示、一键编译、正向/反向搜索在代码和PDF间跳转等所有功能。对于subcaption等宏包补全功能尤其好用。Overleaf在线协作编辑平台无需本地安装内置大量模板。非常适合团队合作或初学者入门。其实时编译和错误提示也很直观。TeXstudio / TeXmaker经典的专用LaTeX IDE功能全面稳定可靠。编译链对于包含子图、中文、参考文献、交叉引用的复杂文档推荐使用XeLaTeX或LuaLaTeX编译器。它们对现代字体和宏包的支持更好。在VS Code的settings.json中可以为.tex文件配置latex-workshop.latex.tools: [ { name: xelatex, command: xelatex, args: [-synctex1, -interactionnonstopmode, -file-line-error, %DOC%] } ], latex-workshop.latex.recipe.default: xelatex文件组织your_project/ ├── main.tex # 主文档 ├── preamble.tex # 导言区设置宏包、自定义命令等 ├── chapters/ # 各章节 │ ├── intro.tex │ ├── method.tex │ └── experiment.tex ├── figures/ # 存放所有图片 │ ├── result_a.pdf │ ├── result_b.pdf │ └── ... └── references.bib # BibTeX参考文献数据库在main.tex中用\input{preamble}和\input{chapters/intro}来组织内容。在preamble.tex中集中管理所有宏包和设置如\graphicspath{{figures/}}。最后关于子图和并列图我最深刻的体会是规划先行。在画图或者生成结果图的时候就要提前想好它们最终在文档里要以何种形式组合。是1x22x2还是1x3子图之间的尺寸比例如何标题要写什么提前规划好这些能让你在后期排版时事半功倍避免反复调整图片尺寸和重做图的麻烦。好的多图排版不仅仅是技术实现更是作者逻辑思维和审美能力的体现。一张清晰、专业的组合图能让你的论文或报告在第一时间就给读者留下严谨、专业的印象。