化学与物理图

在 LaTeX 中绘制费曼图的经典方法里,每幅图会变成 字体中的一个字符。这不是比喻。在 TeX Live 2024 上把 feynmf 的图交给 METAFONT,它会报告 "Font metrics written on myfd.tfm",接着是 "Output written on myfd.600gf (1 character, 4340 bytes)"——字符数为一。一幅散射过程图,被铸成了带字宽表的活字。科学图形各有本领域的“绘图语法”,而领域专用宏包正是把这种语法直接当作输入。本页从“各自用来做什么”和“在哪个引擎上运行”两条线索,梳理化学中的 mhchemchemfigXyMTeX,物理中的 tikz-feynmanfeynmf,以及分子轨道图的 modiagram

即使同属“化学与物理图形”,工具也会随目标明显分开。先看对应表把握全局,再逐一细看。

宏包领域可制作的内容引擎 / 编译遍数
mhchem化学作为文字排版的化学式与反应式(H2O、2H2+O2 -> 2H2O)任意引擎;一遍
chemfig化学结构式、骨架式与反应方案基于 TikZ;pdf、lua、xe 均可
xymtex化学结构式;用命令直接调用环与骨架标准 LaTeX,另有 PostScript 与 PDF 模式
tikz-feynman物理费曼图;写出顶点即自动布局以 LuaLaTeX 为前提;其他引擎布局退化
feynmf / feynmp物理费曼图;每幅图成为字体字形或 MetaPost 图形两遍;需另行运行 mfmpost
modiagram化学/物理分子轨道(能级)图基于 TikZ;一遍

在正文中书写化学式与反应式 —— mhchem\ce{}

mhchem 不是画结构图的工具,而是 把化学式和反应式作为文字排版 的宏包。用 \usepackage[version=4]{mhchem} 载入,把表达式写进核心命令 \ce{...}(chemical equation)里。它的巧妙之处在于 按自然方式输入就能得到正确的化学排版:紧跟元素符号的数字自动变成下标(\ce{H2O}),带 ^ 的数字或符号变成电荷上标(\ce{SO4^2-})。箭头可直接键入 ->(正向)、<=>(平衡)、<-(逆向),+ 会以反应物相加的正确间距排版。

document.tex
\usepackage[version=4]{mhchem}
% ...
\ce{2 H2 + O2 -> 2 H2O}
\ce{CO2 + C ->[\Delta] 2 CO}
\ce{H2O <=> H+ + OH-}
\ce{Ba^2+ + SO4^2- -> BaSO4 v}
\ce{C\bond{-}C}

这些依次排出:水的生成(系数与下标自动对齐);加热,其中 ->[\Delta]条件标签放在箭头上方(写 ->[上][下] 可上下并列);水的电离平衡,使用双向平衡箭头;硫酸钡沉淀,末尾的 v 变成 向下箭头(逸出气体用 ^);以及用 \bond 表示的单键符号。\ce{} 在正文和 $...$ 数学环境中都能用。它做不到的是 绘制结构式——键线与环不在范围内。需要骨架图时,就该用下面的 chemfig。目标相同的后起宏包还有 chemformula,它通过 \ch{...} 提供这一思路。

一笔画出结构式 —— chemfig 的键符号与角度

chemfig 是绘制分子 结构式(骨架图) 的常用工具;它基于 TikZ,用“键与分支的迷你语言”描述分子。载入只需 \usepackage{chemfig},核心命令是 \chemfig{...}。语法的核心是 键符号角度 两点。键 —— - 单键、= 双键、~ 三键 —— 放在原子之间,方向在紧随其后的方括号中指定。[2] 这样 0 到 7 的数字是以 45° 为步长的预定义方向[0] 是东(右),逆时针数去 [2] 是正上,[4] 是西,[6] 是正下。任意角度用冒号写成绝对值,例如 [:30]。圆括号 (...) 从主链分出支链。

document.tex
\usepackage{chemfig}
% ...
% methane: hydrogens west, up, down, east
\chemfig{H-C(-[2]H)(-[6]H)-H}

% benzene: alternating bonds, then the inscribed-circle form
\chemfig{*6(=-=-=-)}
\chemfig{**6(------)}

在甲烷的例子里,H-C 先在碳的 西侧 放一个氢;接着的分支 (-[2]H)(-[6]H)正上正下 加氢;最后的 -H东侧(默认方向)伸出一个氢,构成十字形的 CH4。苯的例子中,*6(...) 表示 六元环,括号里的 =-=-=- 让单键与双键交替。* 生成普通环;把它写成两个,即 **,则得到内嵌圆的芳香环表示。chemfig 还能绘制 反应方案:用 \schemestart ... \schemestop 包起来,排列分子,再用 \arrow 插入箭头。写 \arrow{->[试剂]} 可在箭头上标注试剂或条件,\arrow{<=>} 则生成平衡箭头。

latex
\schemestart
  \chemfig{H-C(-[2]H)(-[6]H)-H}
  \arrow{->[\small oxidation]}
  \chemfig{O=C(-[2]H)-[6]H}
\schemestop

这是一条从左到右的方案:从甲烷结构式出发,经过表示氧化的带标签箭头,到达甲醛结构式。由于 chemfig 建立在 TikZ 之上,它在 pdfLaTeX、LuaLaTeX、XeLaTeX 下都能运行,通常不需要额外的驱动设置(在经由 DVI 的 pLaTeX 下请指定 dvipdfmx)。TeX Live 2024 附带的是 1.66 版(2023 年 12 月 28 日),作者为 Christian Tellechea。

把整个环当命令调用 —— XyMTeX

绘制结构式的另一位老将是 XyMTeX(藤田真作 编写),其思路与 chemfig 恰好相反。chemfig 是“把键一笔画出来”,而 XyMTeX 则是 把整个环或骨架当作命令调用,并以参数传入取代基。例如写 \bzdrv{1==Cl;4==OH},就会得到 1 位带 Cl、4 位带 OH 的苯环——用位号指明“什么接在哪里”,与化学命名法的写法如出一辙。它的优势在于能用固定、结构化的命令稳定排出复杂的稠合多环与取代模式。

document.tex
\usepackage{xymtex}
% ...
% benzene with Cl at position 1 and OH at position 4
\bzdrv{1==Cl;4==OH}

若是从头开始写,多数人会选择记法更直观、维护也更活跃的 chemfig。XyMTeX 至今仍然有用,是在维护已用它写成的稿件时,以及对用位号指定的写法已经熟练的场合。输出方面,它支持 LaTeX 标准模式以及 PostScript 与 PDF 模式。

tikz-feynman 以 LuaLaTeX 为前提 —— pdfLaTeX 下的警告

请用 LuaLaTeX 编译。 在其他引擎下它“能跑”,但自动布局会失效,而且与布局相关的键 不是被悄悄忽略,而是逐条以警告报告出来。在 TeX Live 2024 上用 pdflatex 试验,先出现 "Package tikz-feynman Warning: LuaTeX is required if you wish to have vertices automatically placed.",接着对 horizontalnode distancelevel distancesibling distance 各给出一条 "The key you tried to use ... requires LuaTeX. It will be ignored."。原因是布局算法是用 Lua 写的;换成 lualatex 后一条警告都没有。

还有一点,注意 compat 的编号。常被引用的 \usepackage[compat=1.0.0]{tikz-feynman} 在 TeX Live 2024 上会给出警告:"Package tikz-feynman Warning: The preamble requested version 1.0.0, but the system version is 1.1.0. This may change some diagrams."。附带的版本是 1.1.0(2016 年 2 月 5 日),所以应写 compat=1.1.0。这个键的作用是让你在宏包更新可能改变图形时能够察觉,因此正确用法是 与自己环境中实际安装的版本一致(主版本号不一致会直接报错,而非警告)。

document.tex
% compile with lualatex
\usepackage[compat=1.1.0]{tikz-feynman}
% ...
% one-shot command: e+ e- -> mu+ mu- via a photon
\feynmandiagram [horizontal=a to b] {
  i1 -- [fermion] a -- [fermion] i2,
  a -- [photon] b,
  f1 -- [fermion] b -- [fermion] f2,
};

这幅图是教科书式的 s 通道散射:左侧的粒子对在顶点 a 汇合,ab 之间由一条 波浪线(光子) 相连,右侧再分裂成另一对。线的样式用 [fermion](带箭头的直线)、[photon](波浪线)、[gluon](螺旋线)等指定,而 顶点只要写出名字就会隐式创建horizontal=a to b 是“把 a 和 b 水平放置”的布局提示,正是刚才 pdfLaTeX 警告说会忽略的那个键。要精细控制位置,可在 tikzpicture 内打开 feynman 环境,用 \vertex 放置顶点,再用 \diagram* 连接。

feynmf / feynmp —— 诞生于 1989 年的两遍方式

这一族采用 在 LaTeX 之外排出图形,再把结果引入 的两遍方式。feynmf 使用 METAFONT,feynmp 使用 MetaPost。作者是 Thorsten Ohl,feynmf.sty 的版权声明可追溯到 1989 年——早于 LaTeX2e(1994 年)。TeX Live 2024 附带的是 v1.08,其内部版本管理时间戳仍停在 1996 年。换个说法就是:将近三十年没有改动的必要。

写法是声明式的。图按文件名分组在 fmffile 环境中;在其中的 fmfgraph(或 fmfgraph*)里,用 \fmfleft\fmfright 给出外部腿,用 \fmf{...} 给出线。你不必写顶点坐标——只需说明 哪条腿经由哪个顶点通向何处,其余的布局由它完成。\fmf{fermion}{i1,v1,o1} 的意思是“从 i1 经 v1 到 o1 画一条费米子线”。

document.tex
% feynmp-auto runs MetaPost for you: pdflatex -shell-escape document
\usepackage{feynmp-auto}
% ...
\begin{fmffile}{myfd}
  \begin{fmfgraph*}(120,80)
    \fmfleft{i1,i2}
    \fmfright{o1,o2}
    \fmf{fermion}{i1,v1,o1}
    \fmf{photon}{v1,v2}
    \fmf{fermion}{i2,v2,o2}
  \end{fmfgraph*}
\end{fmffile}

这里就接回了本页开头的话。在 feynmf 路线上,第一次 LaTeX 运行会写出 myfd.mf,也就是一份 METAFONT 源码;把它交给 mf,图形就被 铸成一套字体。在 TeX Live 2024 上实测的 METAFONT 报告是 "Font metrics written on myfd.tfm" 和 "Output written on myfd.600gf (1 character, 4340 bytes)"。一幅图就是一个字符。于是第二次 LaTeX 运行不过是把这套字体的第一个字符排进正文而已。feynmp 路线(经 MetaPost)产出的是普通图形而非字体,所以现代的 PDF 工作流通常选它。

实际使用中,载入 feynmp-auto 更省事,它会自动执行 MetaPost。但既然要启动外部程序,就需要 --shell-escape,而且忘了加会很麻烦——在 TeX Live 2024 上试验,它既不警告也不报错,只是 生成了一个没有图的 PDF。如果图的位置是空白,请先怀疑是不是漏了 -shell-escape。加上之后跑两遍,mpost 就会运行,图也就进去了。

分子轨道图的 modiagram —— MOdiagram 环境已被弃用

请使用小写的环境名 modiagram 网上的示例——包括本页的旧版——普遍写作 \begin{MOdiagram},但在 TeX Live 2024 的 modiagram 0.3a 上使用它会得到警告:"Package modiagram Warning: The environment MOdiagram is deprecated. Use modiagram instead."。图形仍会出来,但没有理由继续使用一个终将消失的名字。改成小写,警告就没有了。

分子轨道图(MO 图) 位于化学与物理的交界处:它展示原子轨道(AO)如何组合成成键与反键分子轨道(MO),并按能量高低纵向排列。专为此而作的是 modiagram(Clemens Niederberger 编写;TeX Live 2024 中为 0.3a),基于 TikZ。用 \usepackage{modiagram} 载入,在环境中用 \atom 写出左右原子轨道,用 \molecule 写出连接它们的分子轨道。

document.tex
\usepackage{modiagram}
% ...
% lower-case environment name: MOdiagram is deprecated
\begin{modiagram}
  \atom{left}{ 1s = {0; up} }
  \atom{right}{ 1s = {0; up} }
  \molecule{ 1sMO = {1; pair, } }
\end{modiagram}

这是最简单的 MO 图,表示氢分子 H2。\atom{left}\atom{right} 各在 1s 轨道中放入一个自旋向上的电子{0; up} 中的 0 是能级),\molecule 把两者合并为一个成键轨道并放入 电子对pair)。只要把占据方式(updownpair)和能级高度作为参数给出,由横线与自旋箭头组成的能级图就会自行搭起。这类图也可以用 纯 TikZ 绘制,但 modiagram 专门面向 MO 图的规范,因此能更简短、更准确地写出这些定型图。

如何取舍,以及编译中容易卡住的地方

选择直接取决于 你想做什么。正文中书写化学式与反应式,用 mhchem;绘制结构式与反应方案,用 chemfig(复杂稠合环若适合命令式方法,则用 XyMTeX);画费曼图,用 tikz-feynman(旧环境或既有稿件用 feynmf / feynmp);画分子轨道图,用 modiagrammhchemchemfig 不是竞争而是互补,常见做法是在同一文档中并用——正文中的方程用 mhchem,另起一行的骨架图用 chemfig

就经验而言,编译卡住的原因大致只有三类。引擎不对——tikz-feynman 的布局需要 LuaLaTeX。漏了 --shell-escape——feynmp-auto 会一声不吭地丢掉图。以及 编译遍数——feynmf / feynmp 要跑两遍图才会出现。此外,chemfigmodiagram 基于 TikZ,图一多计算就变重。用 tikzexternalize 缓存图形,或用 standalone 类单独编译图形,编辑时的等待会明显减少。