news 2026/10/14 17:37:51

LaTeX图片插入实战:figure环境、浮动体与位置参数详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LaTeX图片插入实战:figure环境、浮动体与位置参数详解

最早用 LaTeX 写毕业论文那会儿,被图片排版折腾得够呛。图总是不在我想让它出现的位置出现,要么跑到好几页之后,要么跟正文叠在一起,要么宽度直接冲出页边距。后来把图片插入的机制彻底摸了一遍,才算真正理解了 LaTeX 的思路——它并不是故意抬杠,而是有一套属于自己的浮动体规则。这篇文章是图片插入经验的第一篇,我会把最常用到的知识点串一遍:figure 环境的基本结构、位置参数的选择逻辑、图片尺寸的控制方式、多图和跨栏的处理方法,以及图片格式与编译引擎之间的匹配关系。内容比较基础,但都是实战里反复用到的部分,尤其适合刚接触 LaTeX、正在写论文或者准备做 slide 的同学参考。

1. 为什么图片在 LaTeX 里"不听话":figure 环境的核心机制

很多人刚开始接触 LaTeX 图片插入时,第一个动作就是在某个段落中间直接写一句\includegraphics{xxx.png},然后发现图片是真的"插"在文本流里,位置僵硬得没法看,还容易和文字挤在一起。稍微用了 figure 环境之后,图片又会"乱跑"。要理解这些现象,得先搞清楚 LaTeX 对图片的定位:图片不是正文的一部分,而是被当成一个"浮动体"来处理的。

浮动体这个概念是问题的根源,也是解决问题的关键。LaTeX 在排版时,把正文拆成一个个段落,按照顺序填入页面。如果一张图片正好处在一个页面剩余空间不够大的位置,直接硬塞进去会留下大块空白,观感极差。浮动体机制允许 LaTeX 把这张图"挪"到当前页的顶部、底部,或者下一页,再在原来的位置附近自动调整文字留白,最终排版结果会更紧凑、更均匀。换句话说,figure环境给了排版引擎调度图片位置的权力,代价就是图片不一定待在源码里写的那个位置。

一个最基本的图片插入结构是这样的:

\documentclass{article} \usepackage{graphicx} \begin{document} \begin{figure}[htbp] \centering \includegraphics[width=0.8\textwidth]{figures/example.pdf} \caption{这里是图片标题} \label{fig:example} \end{figure} \end{document}

这里面有几件需要特别记住的事。\usepackage{graphicx}必须在导言区内声明,它提供\includegraphics命令和尺寸控制选项。\centering表示图片在环境中水平居中,它和\begin{center}不一样,后者会额外增加上下间距,还会改变环境内的段落结构,排版时容易出现间距异常,所以常规做法直接使用\centering。

\caption{...}生成图题,在大多数文档类里默认显示成"图 1:..."之类的格式。\label{fig:example}用于交叉引用,正文里写如图~\ref{fig:example} 所示,就能自动生成图编号。这里有一个非常容易踩的坑:\label必须放在\caption之后,因为\ref抓取的是"当前被引用环境的计数器当前值",如果 label 在 caption 之前,计数器还没来得及更新,引用出来往往是上一张图的编号或直接是??。

用 figure 环境还有两个额外收益:第一,所有带caption的 figure 环境会自动收入"图目录",在\listoffigures命令处生成插图目录,这是写长文档时的刚需功能;第二,浮动体本身会在页面排版时自动避让文字,避免图片把正文挤得支离破碎。

如果你只是想在正文里插入一个不参与浮动、不编号、不进入目录的小图形,比如一个简单的示意图,也可以不套 figure 环境,直接使用\includegraphics。不过这种情况比较少见,我自己的习惯是:凡是需要编号、需要被引用、需要出现在图表目录里的图,一律放进 figure;如果是文档内随手画的一个装饰性徽标或示意图,则直接\includegraphics裸嵌。分清这两类需求,后面才不会因为随便加了[H]或者删掉了浮动环境而酿成各种莫名其妙的排版事故。

2. 位置参数选得好,图就不会乱跑:h、t、b、p 的真实行为与推荐组合

figure 环境后面方括号里的[htbp]才是真正决定图片往哪跑的钥匙。很多入门教程只是把它当成一个"万能咒语"抄下来,却不知道每个字母的具体含义,遇到图片异常跑位时自然无从排查。这几个字母的含义如下表所示:

参数英文含义实际排版效果
hhere尽量放在源码所在位置附近
ttop尽量放在当前页顶部
bbottom尽量放在当前页底部
ppage of floats单独组成一页,只放浮动体
!override忽略内部限制规则,强制尝试

LaTeX 会按照你给的字母顺序依次尝试放置位置。比如[ht]的意思是:先尝试放在当前位置附近,如果放不下,就放到页面顶部;如果顶部也放不下,再尝试下一页的顶部。对于[htbp]这种综合参数,引擎会逐个候选位置试探,选择第一个能塞进去的地方。值得注意的是,大多数标准文档类默认不允许h单独出现时被强制满足——也就是说不加t或b作为备选时,很多"当前位置"其实空间不够。这也是为什么你写[h]有时会看到图片跑到了后面几页,因为你根本没给引擎留下其他选择。

!是一个容易被忽略的字母。它不改变位置候选本身,而是告诉 LaTeX:不用管那些用来限制浮动体数量、防止某一页文字被挤掉的比例规则,尽量按候选顺序满足位置。实际使用中,[!htbp]往往比[htbp]更"听话"。但凡事有代价,如果一页里有好几张[!htbp]的大图,引擎可能为了满足位置而把正文压缩得很难看,或者产生大量空白。所以!用在一两张"必须放在这个位置附近"的图上比较合适,整篇文档每张图都用它,效果反而很糟。

还有一个高频使用的参数是H,它来自float宏包,写法是:

\usepackage{float} \begin{figure}[H] ... \end{figure}

H表示"绝对放在源码当前位置",是比h强硬得多的要求。它的优点非常直观:图片会老老实实出现在你写代码的地方,排版过程完全可控。缺点同样明显:如果图太高,接近或超过整页可用高度,就会出现 "Float too large" 这类编译警告,图会被截断甚至报错。另外[H]会抑制浮动机制,导致图片不会自动调整位置来"填白",如果图片后面的文字很少,页面底部可能出现比较大的空白。

我在实际写作中的建议是:普通单栏正文、图片高度不超过半页的情况下,优先用[htbp],让 LaTeX 自己调度;如果图片必须紧跟某段论述,比如实验结果和结论要严格对应,就用[H],但要提前检查图片高度是否合适。对于双栏文档中的单栏图片,[htbp]的表现通常也不错,遇到特殊情况再单独调整。

还有一个可能性很容易被忽视:图片跑到奇怪的位置,并不全是位置参数的问题,而是它前面的浮动体占满了当前位置的配额。比如连续插入两张图,第一张是[ht],第二张也是[ht],但当前页只允许一个顶部浮动位,第二张就会被推到下一页,看起来就像"跳过了好多正文"。这种情况下,与其纠结参数,不如从结构上调整——把其中一张图改成[b],让它们一个在页顶一个在页底,或者把两张图放到同一个 figure 环境里并排排版,这样反而更清爽。

3. 图片尺寸控制逻辑:别靠肉眼猜,用相对单位才稳定

在 LaTeX 里控制图片大小,核心命令是\includegraphics的可选参数。最常用的三个是width、height和scale,还有angle可以旋转方向。举个例子:

% 按宽度缩放,高度自动等比 \includegraphics[width=8cm]{figures/example.pdf} % 同时指定宽高,可能拉伸变形 \includegraphics[width=6cm, height=4cm]{figures/example.pdf} % 等比缩放倍率 \includegraphics[scale=0.5]{figures/example.pdf} % 旋转加缩放 \includegraphics[angle=90, width=0.7\textwidth]{figures/example.pdf}

初次接触时容易踩的坑是:直接把图片原来的物理尺寸写进去,比如导出的 PNG 是 1280x720,就写width=12.8cm,结果发现图在页面上大得离谱或小得可怜。原因是图片本身的分辨率和 LaTeX 的排版单位是两套体系:LaTeX 关心的是输出到纸张上的物理宽度,而不是图片的像素数量。同样一张 1280 像素宽的 PNG,输出到 doc 里是几厘米宽,取决于你给width赋的值、文档的字号、页边距等。所以正确做法不是根据原图尺寸猜,而是根据排版版面本身来确定目标宽度。

LaTeX 提供了一组非常有用的相对长度单位,最常用的包括:

  • \textwidth:当前页面正文区域的宽度
  • \linewidth:当前行宽,在多栏模式或列表环境中可能小于\textwidth
  • \columnwidth:当前栏宽度,双栏文档中等于单栏宽度
  • \paperwidth:整张纸的宽度
  • 0.5\textwidth这类比例写法,表示占正文宽度的百分之五十

推荐的写法是:\includegraphics[width=0.6\textwidth]{...}。这样写的好处是,图片宽度始终相对于版面正文宽度设置。哪怕你后来更换了纸张大小、字号、页边距,图片比例都不会失控。对于双栏文档,如果想把图片跨栏放置,一般需要figure*环境并使用\textwidth;如果是单栏内插图,则应该用\columnwidth或0.8\columnwidth,而不是直接照搬\textwidth,否则图片必然超出栏宽。

我个人的习惯是给图片设定一个最大宽度统一逻辑,比如把所有"普通结果图"统一用width=0.85\linewidth,"重要大图"用width=0.95\textwidth,"用于对比的小图"用width=0.15\textwidth。这样全文图片大小有层次,不会出现前一张图巨大、后一张图很小的失衡感。多图并排时,这个思路尤其重要:要提前计算好每张子图宽度,加上中间间距,总和不要超过\textwidth。

还有一个细节值得强调:keepaspectratio参数。如果在同时指定宽高的过程中担心比例失真,可以在参数里加上keepaspectratio=true,LaTeX 会先按宽高两个限制条件中更严格的那一个缩放,从而自动保持原始宽高比。对于不知道该图原始长宽比、又必须同时设置宽高的场景,这个参数是救命的。

\includegraphics[width=6cm, height=4cm, keepaspectratio=true]{figures/example.pdf}

这个写法的效果是:图片会在宽度不超过 6cm、高度不超过 4cm 的前提下,按原始比例等比缩放。很适合论文里统一输出一组大小不一、比例不一的实验截图。

关于单位本身,也顺带提一句。LaTeX 里常见的长度单位有cm、mm、in、pt,还有em、ex这类随字体变化的单位。一般排版图片只需要cm和相对单位就够用了,但如果你在调整图注与图片之间的距离时,用em会比用cm更贴近文字排版的感觉,因为em和字号挂钩,换字号之后间距感不会太突兀。

4. 子图、跨栏、绕排:论文里高频出现的几种进阶图片布局

基础图插明白之后,接下来就是实战里几乎躲不掉的几种布局需求。第一种是子图,比如你要在一张图里并排放两到三张小图,每张小图有自己的小标题,整组图还有一个总标题。常见做法有两种:使用subcaption宏包,或者手动用minipage拼图。

subcaption宏包是目前的主流选择,它在subfigure相关宏包的基础上做了很多改进,与标准caption宏包配合也比较顺。用法如下:

\usepackage{subcaption} \begin{figure}[htbp] \centering \begin{subfigure}[b]{0.45\textwidth} \centering \includegraphics[width=\textwidth]{figures/a.pdf} \caption{子图A的结果} \label{fig:sub-a} \end{subfigure} \hfill \begin{subfigure}[b]{0.45\textwidth} \centering \includegraphics[width=\textwidth]{figures/b.pdf} \caption{子图B的结果} \label{fig:sub-b} \end{subfigure} \caption{两组结果的对比} \label{fig:sub} \end{figure}

这里面的\hfill会在两个子图之间插入弹性空白,把它们挤向左右两边。子图宽度取0.45\textwidth而不是一半,是因为中间还需要留出空白,两张 0.45 加起来占 0.9,剩下 0.1 正好用来作间隔。三张图并排时常见分法是0.3\textwidth + \hfill + 0.3\textwidth + \hfill + 0.3\textwidth,自己换算一下,别写死成 0.33。

引用子图的时候,正文里写如图~\ref{fig:sub-a} 所示,就会自动生成类似 "图 3a" 的交叉引用。整体图引用则使用\ref{fig:sub}。这里容易出问题的是:如果你只用了裸的minipage而不加载subcaption,子图的小标题编号就需要手动写,比如自己在minipage里放一行(a),而总图编号和子图编号完全脱节,一旦增删图片,手动编号全乱,所以建议优先用subcaption而不是自己硬拼。

第二种需求是跨栏图。标准双栏文档中,单个figure环境只能放在单栏内,宽度上限是\columnwidth。如果图表比较宽,可以改用figure*环境,让图片横跨两栏放。用法几乎一样,只是环境名多了一个星号:

\begin{figure*}[htbp] \centering \includegraphics[width=\textwidth]{figures/wide.pdf} \caption{一张跨栏的宽图} \label{fig:wide} \end{figure*}

需要提醒的是,figure*在某些文档类中的浮动位置策略跟普通figure不同。比如在标准article双栏模式下,figure*的位置经常被限制在下一页的顶部,放在当前页顶部不一定成功。如果排版目标是"尽量靠近引用段落",那么跨栏宽图往往需要接受"会飘到接下来某一页顶部"的现实。我个人遇到跨栏图时,常常把图放在对应小节的开头附近,并在正文中用\ref明确指过去,这样即使图片稍微偏离源码位置,读者的阅读体验也是连贯的。

第三个常用布局是绕排,也就是文字绕图排列,通常在版面比较紧凑、图片宽度不大时使用。需要引入wrapfig宏包:

\usepackage{wrapfig} \begin{wrapfigure}{r}{0.4\textwidth} \centering \includegraphics[width=0.35\textwidth]{figures/small.png} \caption{右侧绕排的小图} \label{fig:wrap} \end{wrapfigure}

参数中的{r}表示图在右侧,{l}表示在左侧,后面花括号里写的是图片占用的宽度。绕排效果看起来舒服,但限制也很多:图片太长时绕排会把后续文字切得很难看;wrapfigure内部不能包含过长的caption;在列表或缩进环境里使用绕排,常常会出现文字停止绕排、直接跳到图片下方的现象。所以我的建议是:绕排图适合短小的、非关键的辅助性图片,正文段落里需要紧密引用的大图和正式结果图,不要用绕排。

5. 图片格式与编译引擎:一步错步步错的选择题

很多人在图片插入上卡壳,不是命令写错,而是图片格式与编译引擎不匹配。LaTeX 的编译方式会对支持读取的图片格式产生直接影响,这是一个很容易被忽略但非常关键的底层问题。

先梳理一下当前主流的编译引擎:

编译方式常用命令原生支持的图片格式
pdfLaTeXpdflatexPDF, PNG, JPG
XeLaTeXxelatexPDF, PNG, JPG, EPS 等
LaTeX + dvipslatex, then dvipsEPS(严格说需要特殊处理)

如果你是直接双击 IDE 里的编译按钮,大概率走的是 pdfLaTeX 或 XeLaTeX,那么最稳妥的图片格式是 PDF(矢量图)和 PNG/JPG(位图)。但如果你的模板历史比较久,或者你拿到的图片源文件只有 EPS 格式,直接用 pdflatex 编译会报! LaTeX Error: Unknown graphics extension: .eps这样的错误。解决方式有两个:一是用工具把 EPS 转成 PDF,再插入;二是在导言区加载epstopdf宏包,让编译过程自动把 EPS 转成 PDF。加载方式:

\usepackage{epstopdf}

需要注意,epstopdf只是把 EPS 转成 PDF,并不会改善 EPS 内部内容的清晰度。PDF 本身就是矢量格式,转换后一般不会损失质量。如果你在论文写作时拿到的是.eps文件,又嫌转换麻烦,也可以直接用\includegraphics{figures/xxx.eps}配合 latex-dvips 编译链,但现代 Overleaf 和大多数本地环境默认不是这条链路,所以更推荐转换成 PDF 后再插入。

位图选择上,png适合截图类图片,jpg适合照片或带渐变的图像。截图尽量保存成 PNG,因为截图里的文字和线条是硬边,JPG 压缩容易产生杂色和模糊。如果图片里有大量文字内容,比如软件界面截图,建议尽量在导出横幅时把文字放大到合适字号再截图,否则放到 PDF 里整体缩小时,界面小字会糊成一团。

还有一个细节:PNG 图片的分辨率。LaTeX 不会帮你提升图片清晰度,它只是把既定像素映射到目标物理尺寸。假设一张图宽度目标为 10cm,原图宽度如果只有 300 像素,那么换算下来每厘米只有 30 像素,放大打印必然惨不忍睹。专业期刊一般要求图片不低于 300 DPI,换算方法很简单——目标宽度为 10cm 约等于 3.94 inch,300 DPI 意味着原图宽度至少约为 1181 像素。图片从工具里导出的时候,先算好这个数,免得最后打印出来才发现模糊。

图片命名和路径的问题也值得单独说。LaTeX 对文件名里的空格极为敏感,路径中含空格经常会导致图片找不到,报错信息还可能很迷惑。建议所有图片文件统一用小写英文字母和连字符或下划线,不要有空格、中文、特殊符号。比如figures/experiment-result-01.pdf这种命名方式,既方便查找,也能兼容大多数编译环境和模板。如果你经常遇到图片路径对但就是编译不过的情况,先检查文件名里是不是有空格或中文路径。

6. 图片插入的经典翻车现场与对应排查手段

最后一部分,说几个我自己包括身边同事都遇到过、且极具迷惑性的编译问题。把它们集中放在一起,可以当作排查手册用。

第一个坑:图片文件存在,但编译报File not found。这种情况九成是路径问题。一是文件名写错,比如figure和figures目录搞混;二是路径含有空格;三是 LaTeX 工作目录和源文件目录不一致。排查顺序建议是:先确认源文件所在目录结构,再在\includegraphics中用相对路径从主文件所在目录出发,不要写绝对路径,否则换到另一台机器或 Overleaf 里很容易出错。

第二个坑:编译通过,但图片不显示,只留下一个空白方框或一片区域。常见于使用 dvips 编译链时插入 JPG/PNG,或者在 pdfLaTeX 下插入了 EPS 又没有启用自动转换。解决办法是统一格式或切换引擎。另一个可能原因是图片本身导出损坏,用本地图片查看器打开确认一下是否正常。

第三个坑:图片宽度超出了页边距,编译警告里出现Overfull \hbox。这是我几乎每次写完初稿都会检查一类问题。原因多半是直接用了图片原始物理宽度,而不是相对宽度。解决方法是把图片宽度改成\textwidth的相对比例,比如width=0.8\textwidth,必要时开启keepaspectratio。

第四个坑:Float too large for page by ... points。这个警告的直接意思是浮动体高度超过了页面可用空间,常见于图太高,或者用了[H]、[h]却仍然硬塞。解决方式:缩小图片高度,或者改用[b]/[p],让图片有更多空间可以调整。如果图确实很长,比如一张流程图,考虑拆成多张子图,或者用\rotatebox旋转一下。

第五个坑:\ref引用图片编号显示??或引用到上一张图。这个问题十有八九是\label的位置写错了,把它挪到\caption之后即可。另外还有一个隐蔽原因:\label写在了 figure 环境外面,而环境结束后计数器状态可能已经变化。

第六个坑:同一页连续放了两张图,结果两张图全跑到后面去了,正文出现大片空白。这是浮动体配额机制导致的,可以用三个办法解决:把两张图放进同一个 figure 环境用 minipage 并排;把其中一张改成[b]放在页底;或者在图片之间增加足够的文字,让引擎有内容可以重排。

还有一个我在多栏模板里常踩的坑:figure*里的宽图出现在全文最末尾,或者在双栏排版中被当成普通figure处理。类文件对figure*的支持并不完全一致,尤其是一些自定义模板。遇到这种情况,建议把figure*的位置往前或往后调整,或者干脆用普通figure加\textbf、\textwidth跨栏技巧重排,但后者工作量大,不作为首选。

最后提一个实用习惯:写长文档时,我习惯在正文第一次引用某张图时,直接写"如图~\ref{fig:xxx} 所示",避免使用"下图、上图"这类依赖实际位置的表述。因为 LaTeX 浮动机制的存在,排版后图片实际位置不一定稳定,用"下图"很可能在正式版里变成"上上图"。

关于图片插入的基础部分,我暂时就总结到这。说到底,LaTeX 用力最猛的地方,恰恰是它把图片当成有编号、可调度、可索引的文档对象来对待,而不是简单地把图"画"在页面上。想让它合作,就得顺着它的浮动体机制来。图片插入这块后面还有很多可以展开的话题,比如图注的精细化排版、绘图工具导出的注意事项、跨平台字体对图片的影响等,我会在后续的文章里继续整理。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 17:37:33

端侧AI样机验收:五项工程检查方法,覆盖功能、性能、功耗与稳定性

1. 项目概述1.1 为什么"样机验收"成了端侧 AI 落地中最容易翻车的一环先说个自己踩过的坑。早两年做某智能家居项目的端侧语音唤醒方案,模型在实验室跑得好好的,识别率、延迟、功耗各项指标都漂漂亮亮,结果到了样机量产验证阶段&am…

作者头像 李华
网站建设 2026/10/14 17:37:13

MATLAB手写Softmax实现:数值稳定与梯度可解释性实战

1. 项目概述:为什么在MATLAB里亲手实现Softmax比调用现成函数更有价值Softmax求解多分类问题的MATLAB实现——这标题乍看像教科书习题,但实际是机器学习工程落地中一个被严重低估的“基本功训练场”。我带过不少刚从课程设计转到工业项目的开发者&#x…

作者头像 李华
网站建设 2026/10/14 17:37:13

STM32交通灯控制系统实战:状态机、定时器与工程避坑指南

简介:这是一套面向嵌入式初学者与电子类专业学生的STM32交通灯控制系统完整实践资料,围绕ARM Cortex-M内核微控制器展开,解决交叉路口信号灯智能化控制这一典型实时应用问题。压缩包共191个文件,约9.28MB,以c源文件、h…

作者头像 李华
网站建设 2026/10/14 17:34:33

Lua脚本引擎实战:从API绑定到游戏自动化脚本避坑

简介:面向游戏脚本开发及LUA引擎研究者的LUA 4脚本引擎源码包,专门适配大话西游2.0.78版,采用Visual C 8编写,可在Windows XP/2003/Vista/7系统下通过Visual Studio 2005完成编译。一个值得注意的细节是:编译前需将src…

作者头像 李华