其他绘图系统

TikZ 如今是绘图的事实标准,但它不是唯一选择。还有一些早于 TikZ、至今仍有用途的绘图系统:借助 PostScript 能力的 PSTricks,擅长图式的老牌 Xy-pic,可处理 2D 和 3D 的独立语言 Asymptote,以及继承 METAFONT 血脉的 MetaPost。本页整理这些非 TikZ 绘图系统各自是什么、何时应使用,尤其关注各系统在“输出流程”上的特点。新项目通常用 TikZ 就足够;这些系统主要是为维护旧文档、绘制 3D,或进入特定生态而需要了解。

首先默认选 TikZ

进入正题前,先明确建议。如果今天开始在 LaTeX 中画图,正确做法是 先考虑 TikZ。TikZ 仍在积极维护,可在 pdflatexlualatexxelatex 下运行且不需要额外外部工具,与文档字体和颜色自然融合,周边还有大量库(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。下面是最小示例。

latex
\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。

terminal
latex figure.tex
dvips figure.dvi -o figure.ps
ps2pdf figure.ps

如果必须放进 pdflatex 工作流,或想混用 PNG/JPEG 图片,也有绕行办法。pst-pdfauto-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] 这样组合则表示对角方向(右下一格)。若要给箭头加标签,可复用数学上下标的记法:^ 把标签放在箭头上方(左侧),_ 把标签放在下方(右侧)。

latex
\[
\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-cdtikz-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,完成的图形就会被读入。

terminal
pdflatex document
asy document-*.asy
pdflatex document

手动执行这三步很繁琐,所以实际使用中通常交给 latexmk 自动化。Asymptote 图也可以不嵌入文档,而是写成 独立的 .asy 文件,再用 asy figure.asy 单独运行,输出 PDF、EPS,或输出到包含交互式 3D 的格式。下面是一个最小 .asy 示例。

latex
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 为前提)。下面是一个最小示例。

document.tex
% 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。fullcirclepencirclescaled 都是 MetaPost 的内置词汇。

MetaPost 生态中一个重要部分是 MetaFun。它是面向 MetaPost 的高功能格式,排版系统 ConTeXt 通过 MetaFun 深度集成 MetaPost。对 ConTeXt 用户来说,MetaPost(通过 MetaFun)是核心作图手段。相反,如果主要使用 LaTeX,通常日常使用 TikZ,而把 MetaPost 作为在需要 METAFONT 风格曲线描述或与 ConTeXt 联动时应了解的工具。

体系比较与选择

把这四个体系按输出路径、引擎和强项排列,可得到下表。共同的原则是:新项目先从 TikZ 开始;这里列出的体系只有在有特定理由时才选择,例如既有文档、3D,或某个特定生态系统。

体系输出路径 / 引擎强项 / 主要用途
PSTrickslatex → dvips → ps2pdf;或 pst-pdf/auto-pst-pdf(需要 --shell-escape),或 XeLaTeX高质量 PostScript 填充与效果;既有文档很多
Xy-pic在普通 LaTeX 下工作(不需要特殊路径)交换图(老牌工具);现代替代是 tikz-cd
Asymptotelatex/pdflatex → 外部 asy → 再次 latex(用 latexmk 自动化);或独立 .asy严肃的 2D 和 3D;带坐标轴的立体与曲面
MetaPostmpost 处理 .mp;或 LuaLaTeX + luamplibmplibcode(无需外部工具)METAFONT 风格曲线;ConTeXt(MetaFun)的核心

一个实用的经验法则:如果是 维护既有文档,就应能读写该文档原本使用的体系(PSTricks 或 Xy-pic)。如果需要 3D 图形,Asymptote 是首选。如果使用 ConTeXt,MetaPost(MetaFun)最自然。若要新画 交换图,应选择 tikz-cd 而不是 Xy-pic。至于不属于这些情况的大多数作图,最稳妥的选择是 TikZ,因为它不需要额外外部工具,也不需要特殊输出路径。