TikZ 如今是绘图的事实标准,但它不是唯一选择。还有一些早于 TikZ、至今仍有用途的绘图系统:借助 PostScript 能力的 PSTricks,擅长图式的老牌 Xy-pic,可处理 2D 和 3D 的独立语言 Asymptote,以及继承 METAFONT 血脉的 MetaPost。本页整理这些非 TikZ 绘图系统各自是什么、何时应使用,尤其关注各系统在“输出流程”上的特点。新项目通常用 TikZ 就足够;这些系统主要是为维护旧文档、绘制 3D,或进入特定生态而需要了解。
首先默认选 TikZ
进入正题前,先明确建议。如果今天开始在 LaTeX 中画图,正确做法是 先考虑 TikZ。TikZ 仍在积极维护,可在 pdflatex、lualatex、xelatex 下运行且不需要额外外部工具,与文档字体和颜色自然融合,周边还有大量库(tikz-cd、PGFPlots、circuitikz 等)。TikZ 本身见“TikZ 基础”页面。
那么为什么还要了解其他系统?主要有三个理由。第一是 现有文档:旧论文、书籍、模板可能用 PSTricks 或 Xy-pic 写成,维护或修订时必须能读懂。第二是 3D:正式的三维图中,Asymptote 最擅长。第三是 特定生态:在 ConTeXt 世界中,MetaPost(通过 MetaFun)是核心绘图手段。下面依次说明。
PSTricks:PostScript 的力量
PSTricks 是一组宏,可从 TeX/LaTeX 源码中直接调用 PostScript 的绘图功能。顾名思义,它内部使用 PostScript,因此填充、渐变、坐标变换等质量很高。在导言区用 \usepackage{pstricks} 加载,图写在 pspicture 环境 中。打开环境时给出坐标范围,即左下角和右上角,如 \begin{pspicture}(0,0)(4,3)。
基本绘图命令大多从名字就能看出功能。\psline 画线(或折线),\pscircle 画圆,\psframe 画矩形。坐标写在圆括号中,如 \psline(0,0)(3,2);圆用中心和半径指定,如 \pscircle(2,2){1}。要把任意对象(文字或另一幅图)放在指定坐标,用 \rput,写作 \rput(2,1){text}。若位置还需要角度或偏移,也可用 \uput。下面是最小示例。
\begin{pspicture}(0,0)(4,3)
\psframe(0,0)(4,3)
\psline{->}(0,0)(3,2)
\pscircle(2,1.5){1}
\rput(2,1.5){$O$}
\end{pspicture}这会画出一个宽 4、高 3 的矩形框,在其中从原点到 (3,2) 画一条带箭头的线段,再叠加一个以 (2,1.5) 为中心、半径 1 的圆,并在圆心放置数学符号 O。\psline{->} 中的 {->} 指定箭头;在 PSTricks 中,线型、箭头、颜色等可一起作为方括号 [...] 选项给出(如 \psline[linewidth=2pt,linecolor=red]{->}(...))。
这里是 最重要的注意点。PSTricks 依赖 PostScript 的 \special(嵌入 DVI 的特殊指令),因此 不能在直接生成 PDF 的 pdflatex 下直接工作。经典且可靠的路线是经由 DVI:latex → dvips → ps2pdf。也就是先用 latex 生成 DVI,再用 dvips 转成 PostScript,最后用 ps2pdf(Ghostscript)生成 PDF。
latex figure.tex
dvips figure.dvi -o figure.ps
ps2pdf figure.ps如果必须放进 pdflatex 工作流,或想混用 PNG/JPEG 图片,也有绕行办法。pst-pdf 和 auto-pst-pdf 包会在后台只把 PSTricks 部分经由 PostScript 渲染成 PDF 片段,再并入 pdflatex 输出(auto-pst-pdf 会调用外部处理,因此需要带 --shell-escape 运行;同类的 pdftricks 也需要 -shell-escape)。另一条路是用 XeLaTeX 编译:安装 xetex-pstricks 后,xelatex 可在不改源码的情况下处理 PSTricks。
PSTricks 有丰富的扩展包家族,如 pst-plot(函数图)、pst-node(节点和连接)、pst-3dplot(3D 图)等,表现力仍然很高。不过考虑到输出路径的限制,新文档通常用 TikZ 更容易处理。
Xy-pic:图式老将
Xy-pic(包名 xy)是一个历史悠久的通用包,用于排版图和图式。它可在 plain TeX、LaTeX 和 AMS-LaTeX 中工作,长期用于许多领域的图式:范畴论、代数、拓扑,也包括自动机、数据库、化学和谱系图。在 LaTeX 中通常用 \usepackage[all]{xy} 载入,其中 [all] 会启用标准功能集。
最常用的部分,尤其是用于 交换图 的,是 \xymatrix。这是一种像矩阵一样排布图式的模式:和 tabular 一样,条目用 & 横向分隔,行用 \\ 换行。对象之间的箭头用 \ar 命令绘制,目标用方向键给出:[r] 向右,[l] 向左,[u] 向上,[d] 向下;像 [rd] 这样组合则表示对角方向(右下一格)。若要给箭头加标签,可复用数学上下标的记法:^ 把标签放在箭头上方(左侧),_ 把标签放在下方(右侧)。
\[
\xymatrix{
A \ar[r]^{f} \ar[d]_{\alpha} & B \ar[d]^{\beta} \\
C \ar[r]_{g} & D
}
\]这会生成一个交换正方形,A、B、C、D 位于四角:上边是向右的 f,左边是向下的 α,右边是向下的 β,下边是向右的 g。标签 f 位于上方箭头之上,g 位于下方箭头之下。由于图式本身也是数学内容的一种,所以放在陈列数学环境(\[ … \])中。
Xy-pic 在历史上很重要,今天仍可在许多文档中看到,但对于交换图,现代替代方案是基于 TikZ 的 tikz-cd。tikz-cd 更容易处理曲线、复杂箭头和多行复杂图式,错误信息也更友好。合理的分工是:新写内容用 tikz-cd,维护既有 Xy-pic 文档时使用本节知识。两者的详细比较见“交换图”页面。
Asymptote:用于 2D 与 3D 的语言
Asymptote 不是一组 TeX 宏,而是一门 独立的矢量图形语言。它采用类似 C++ 的语法,作为具备变量、函数、循环和类型的完整编程语言来描述图形。它的目标是把 LaTeX 带给科技文本的高质量排版也同样带到图中;突出的特点是能以高质量绘制 不仅 2D,也包括 3D 的图形。由于标签排版使用 TeX,图中的数学内容会与正文使用同样的字体。
要嵌入 LaTeX,可在导言区载入 \usepackage{asymptote},并把图形代码写在 asy environment(\begin{asy} … \end{asy})中。由于其机制,编译需要 三步。首先运行 latex(或 pdflatex),每个 asy 环境的内容会被写出到临时 .asy 文件。接着对这些文件运行外部程序 asy 来生成图形(面向 pdflatex 为 PDF,面向 latex/dvips 为 EPS)。最后再运行一次 latex/pdflatex,完成的图形就会被读入。
pdflatex document
asy document-*.asy
pdflatex document手动执行这三步很繁琐,所以实际使用中通常交给 latexmk 自动化。Asymptote 图也可以不嵌入文档,而是写成 独立的 .asy 文件,再用 asy figure.asy 单独运行,输出 PDF、EPS,或输出到包含交互式 3D 的格式。下面是一个最小 .asy 示例。
import three;
size(6cm);
draw(unitcube);
draw(O--X, red, Arrow3);
draw(O--Y, green, Arrow3);
draw(O--Z, blue, Arrow3);这段 Asymptote 代码导入 three 模块(3D 功能),绘制一个单位立方体,然后从原点沿 x、y、z 轴方向分别画出红、绿、蓝三维箭头。size(6cm) 指定最终尺寸。因此,Asymptote 的强项在于可较自然地编写严肃的 3D 图形,例如带坐标轴的立体和曲面,而这些在 TikZ 中往往很费力。它还有一个名为 xasy 的 GUI 前端,可以交互式绘图,并把结果导出为 .asy 源码供手工编辑。
MetaPost:METAFONT 的谱系
MetaPost 是 John Hobby 对 Knuth 的 METAFONT(描述字体的语言)所做的改作,并将输出改为 PostScript。它继承了 METAFONT 特有的记法,可由点和方向求解并绘制平滑曲线(Hobby 算法),并能以方程的方式声明坐标。传统上它是一门独立语言:用专用程序 mpost 处理 .mp 文件以获得 EPS。
在现代实践中,最方便的做法是 直接内嵌在 LuaLaTeX 中 编写。载入 luamplib 包(\usepackage{luamplib})后,就可以在 mplibcode environment 中直接写 MetaPost 代码。它使用 LuaTeX 内置的 mplib library 来排版图形,因此不需要单独调用 mpost,也不需要 --shell-escape。它可在 PDF 模式和 DVI 模式下工作(DVI 输出以使用 dvipdfmx 为前提)。下面是一个最小示例。
% lualatex で処理する / compile with lualatex
\documentclass{article}
\usepackage{luamplib}
\begin{document}
\begin{mplibcode}
beginfig(1);
draw fullcircle scaled 2cm withpen pencircle scaled 1pt;
draw (-1cm,0)--(1cm,0);
draw (0,-1cm)--(0,1cm);
endfig;
\end{mplibcode}
\end{document}这个 mplibcode 的内容就是 MetaPost 代码。beginfig(1) … endfig 分隔出一个图;它用 1pt 的笔画出半径 1cm(单位圆放大到直径 2cm)的圆,再在圆中各画一条水平和垂直直径。用 LuaLaTeX 处理时,无需外部工具,这个图会直接并入 PDF。fullcircle、pencircle 和 scaled 都是 MetaPost 的内置词汇。
MetaPost 生态中一个重要部分是 MetaFun。它是面向 MetaPost 的高功能格式,排版系统 ConTeXt 通过 MetaFun 深度集成 MetaPost。对 ConTeXt 用户来说,MetaPost(通过 MetaFun)是核心作图手段。相反,如果主要使用 LaTeX,通常日常使用 TikZ,而把 MetaPost 作为在需要 METAFONT 风格曲线描述或与 ConTeXt 联动时应了解的工具。
体系比较与选择
把这四个体系按输出路径、引擎和强项排列,可得到下表。共同的原则是:新项目先从 TikZ 开始;这里列出的体系只有在有特定理由时才选择,例如既有文档、3D,或某个特定生态系统。
| 体系 | 输出路径 / 引擎 | 强项 / 主要用途 |
|---|---|---|
PSTricks | latex → dvips → ps2pdf;或 pst-pdf/auto-pst-pdf(需要 --shell-escape),或 XeLaTeX | 高质量 PostScript 填充与效果;既有文档很多 |
Xy-pic | 在普通 LaTeX 下工作(不需要特殊路径) | 交换图(老牌工具);现代替代是 tikz-cd |
Asymptote | latex/pdflatex → 外部 asy → 再次 latex(用 latexmk 自动化);或独立 .asy | 严肃的 2D 和 3D;带坐标轴的立体与曲面 |
MetaPost | 用 mpost 处理 .mp;或 LuaLaTeX + luamplib 的 mplibcode(无需外部工具) | METAFONT 风格曲线;ConTeXt(MetaFun)的核心 |
一个实用的经验法则:如果是 维护既有文档,就应能读写该文档原本使用的体系(PSTricks 或 Xy-pic)。如果需要 3D 图形,Asymptote 是首选。如果使用 ConTeXt,MetaPost(MetaFun)最自然。若要新画 交换图,应选择 tikz-cd 而不是 Xy-pic。至于不属于这些情况的大多数作图,最稳妥的选择是 TikZ,因为它不需要额外外部工具,也不需要特殊输出路径。