跳到主要内容

TikZ 绘图基础

TikZ(TikZ ist kein Zeichenprogramm,递归缩写)是 LaTeX 中最强大的绘图宏包之一。它允许直接在 LaTeX 文档中创建高质量的图形、图表和流程图,无需依赖外部绘图软件。本章介绍 TikZ 的基础用法。

TikZ 简介

为什么使用 TikZ?

优势说明
矢量图形输出为矢量格式,任意缩放不失真
与 LaTeX 集成使用相同的字体、数学公式
精确控制坐标精确到任意小数位
可编程支持循环、条件等编程结构
版本控制友好纯文本描述,易于 git 管理

基本设置

\usepackage{tikz}

% 可选:加载常用库
\usetikzlibrary{
arrows.meta, % 高级箭头
shapes, % 额外形状
positioning, % 相对定位
calc, % 坐标计算
patterns, % 填充图案
decorations.pathmorphing % 波浪线等装饰
}

绘图环境

TikZ 图形使用 tikzpicture 环境:

\begin{tikzpicture}
% 绘图命令
\end{tikzpicture}

或使用内联命令:

\tikz{\draw (0,0) -- (1,1);}  % 内联图形

基本绘图命令

\draw 命令

\draw 是最常用的绘图命令,用于绘制路径:

% 直线
\draw (0,0) -- (2,0);

% 多段线
\draw (0,0) -- (2,0) -- (2,2) -- (0,2) -- cycle;

% 矩形(简化写法)
\draw (0,0) rectangle (2,2);

基本形状

% 圆形
\draw (0,0) circle (1cm);

% 椭圆
\draw (0,0) ellipse (2cm and 1cm);

% 弧
\draw (0,0) arc (0:90:1cm); % 起始角:终止角:半径

% 抛物线
\draw (0,0) parabola (2,2);

曲线

% 贝塞尔曲线(使用控制点)
\draw (0,0) .. controls (1,2) and (2,0) .. (3,2);

% 网格
\draw[step=1cm, gray, very thin] (0,0) grid (4,4);

样式设置

线条样式

% 颜色
\draw[red] (0,0) -- (1,0);

% 粗细
\draw[thick] (0,0) -- (1,0); % 粗线
\draw[very thick] (0,1) -- (1,1); % 更粗
\draw[line width=2pt] (0,2) -- (1,2); % 指定宽度

% 线型
\draw[dashed] (0,0) -- (1,0); % 虚线
\draw[dotted] (0,1) -- (1,1); % 点线
\draw[dash dot] (0,2) -- (1,2); % 点划线

填充

% 填充颜色
\fill[blue] (0,0) circle (1cm);

% 填充并绘制边框
\filldraw[fill=blue!50, draw=red] (0,0) circle (1cm);

% 渐变填充
\shade[left color=blue, right color=red] (0,0) rectangle (2,1);
\shade[inner color=white, outer color=blue] (1,0.5) circle (1cm);

透明度

\fill[blue, opacity=0.5] (0,0) circle (1cm);
\fill[red, opacity=0.5] (1,0) circle (1cm);

坐标系统

笛卡尔坐标

% 默认单位是厘米
\draw (0,0) -- (3,2); % 3cm 右,2cm 上

% 指定单位
\draw (0,0) -- (3cm,2cm);
\draw (0,0) -- (30pt,20pt);

极坐标

% (角度:半径)
\draw (0:1) -- (90:1) -- (180:1) -- (270:1) -- cycle;

相对坐标

% 使用 ++ 表示相对于前一点
\draw (0,0) -- ++(1,0) -- ++(0,1) -- ++(-1,0) -- cycle;

% 使用 + 表示相对于起始点
\draw (0,0) -- +(1,0) -- +(1,1) -- +(0,1) -- cycle;

坐标计算

\usetikzlibrary{calc}

% 中点
\draw (0,0) -- (2,0);
\fill ($(0,0)!0.5!(2,0)$) circle (2pt); % 中点

% 距离
\fill ($(0,0)!1cm!(2,0)$) circle (2pt); % 距(0,0) 1cm 的点

% 垂直投影
\draw ($(0,0)!(1,1)!(2,0)$) circle (2pt);

节点与标签

节点(node)是 TikZ 中放置文本、形状的重要元素。

基本节点

% 简单文本节点
\node at (0,0) {文本};

% 带名称的节点
\node (A) at (0,0) {A};
\node (B) at (2,0) {B};

% 节点引用
\draw (A) -- (B);

节点样式

% 形状
\node[draw] at (0,0) {矩形}; % 绘制边框
\node[circle, draw] at (2,0) {圆形}; % 圆形
\node[ellipse, draw] at (4,0) {椭圆}; % 椭圆

% 填充
\node[draw, fill=blue!20] at (0,1) {填充};

% 大小
\node[draw, minimum width=2cm] at (0,2) {宽度};
\node[draw, minimum height=1cm] at (2,2) {高度};

节点位置

\usetikzlibrary{positioning}

\node (A) at (0,0) {A};
\node[right=of A] {A右侧}; % 相对定位
\node[below=1cm of A] {A下方}; % 带距离

% 方向选项:above, below, left, right
% 组合:above left, below right 等

节点锚点

每个节点有多个锚点,用于精确定位:

\node[draw, minimum width=2cm, minimum height=1cm] (box) at (0,0) {};

% 锚点示例
\node[above] at (box.north) {上};
\node[below] at (box.south) {下};
\node[left] at (box.west) {左};
\node[right] at (box.east) {右};

% 角落锚点:north west, north east, south west, south east
% 中心锚点:center

箭头与连接

基本箭头

% 箭头样式
\draw[->] (0,0) -- (1,0); % 单箭头
\draw[<-] (0,1) -- (1,1); % 反向箭头
\draw[<->] (0,2) -- (1,2); % 双向箭头

高级箭头

\usetikzlibrary{arrows.meta}

% 使用 arrows.meta 库
\draw[-{Stealth}] (0,0) -- (1,0); % 三角箭头
\draw[-{Stealth[scale=2]}] (0,1) -- (1,1); % 放大箭头
\draw[-{Latex}] (0,2) -- (1,2); % LaTeX 箭头
\draw[-{Circle}] (0,3) -- (1,3); % 圆形端点

% 双箭头
\draw[{Stealth}-{Stealth}] (0,4) -- (1,4);

节点连接

\node (A) at (0,0) {A};
\node (B) at (2,0) {B};

% 直接连接
\draw[->] (A) -- (B);

% 指定锚点连接
\draw[->] (A.east) -- (B.west);

% 曲线连接
\draw[->] (A) to[bend left] (B);
\draw[->] (A) to[bend right=30] (B);

流程图

基本流程图

\usetikzlibrary{shapes.geometric, arrows.meta, positioning}

\begin{tikzpicture}[
node distance=1.5cm,
startstop/.style={rectangle, rounded corners, minimum width=2cm,
minimum height=0.8cm, draw, fill=red!20},
process/.style={rectangle, minimum width=2cm, minimum height=0.8cm,
draw, fill=blue!20},
decision/.style={diamond, aspect=2, minimum width=1cm,
draw, fill=green!20},
arrow/.style={-{Stealth}, thick}
]

\node (start) [startstop] {开始};
\node (input) [process, below of=start] {输入数据};
\node (decide) [decision, below of=input, yshift=-0.5cm] {条件?};
\node (process1) [process, below of=decide, yshift=-0.5cm] {处理1};
\node (process2) [process, right of=decide, xshift=2cm] {处理2};
\node (stop) [startstop, below of=process1] {结束};

\draw [arrow] (start) -- (input);
\draw [arrow] (input) -- (decide);
\draw [arrow] (decide) -- node[left] {是} (process1);
\draw [arrow] (decide) -- node[above] {否} (process2);
\draw [arrow] (process1) -- (stop);
\draw [arrow] (process2) |- (stop);

\end{tikzpicture}

状态图

\usetikzlibrary{automata, positioning, arrows.meta}

\begin{tikzpicture}[
->,
>=Stealth,
node distance=2.5cm,
every state/.style={thick, fill=blue!10},
initial text={}
]

\node[state, initial] (q0) {$q_0$};
\node[state] (q1) [right of=q0] {$q_1$};
\node[state] (q2) [right of=q1] {$q_2$};
\node[state, accepting] (q3) [right of=q2] {$q_3$};

\path
(q0) edge node[above] {0} (q1)
(q1) edge node[above] {1} (q2)
(q2) edge node[above] {0,1} (q3)
(q1) edge[loop above] node {0} ();

\end{tikzpicture}

函数图像

使用 TikZ 绘制

\begin{tikzpicture}
% 坐标轴
\draw[->] (-3,0) -- (3,0) node[right] {$x$};
\draw[->] (0,-1) -- (0,3) node[above] {$y$};

% 函数曲线
\draw[blue, thick, domain=-2:2, samples=100]
plot (\x, {\x*\x}) node[right] {$y=x^2$};

\draw[red, thick, domain=-1.5:1.5, samples=100]
plot (\x, {\x*\x*\x}) node[right] {$y=x^3$};
\end{tikzpicture}

使用 pgfplots 宏包

pgfplots 提供更专业的数据可视化功能:

\usepackage{pgfplots}
\pgfplotsset{compat=1.18}

\begin{tikzpicture}
\begin{axis}[
xlabel={$x$},
ylabel={$y$},
domain=-2:2,
samples=100,
grid=major,
legend pos=north west
]

\addplot[blue, thick] {x^2};
\addplot[red, thick] {x^3};
\legend{$y=x^2$, $y=x^3$}

\end{axis}
\end{tikzpicture}

循环与条件

foreach 循环

% 基本循环
\foreach \x in {0,1,2,3,4} {
\draw (\x,0) circle (0.2cm);
}

% 范围循环
\foreach \x in {0,...,10} {
\draw (\x,0) -- (\x,1);
}

% 带步长
\foreach \x in {0,0.5,...,3} {
\draw (\x,0) -- (\x,0.5);
}

% 双变量
\foreach \x/\y in {0/A, 1/B, 2/C} {
\node at (\x,0) {\y};
}

条件判断

\foreach \x in {1,...,5} {
\ifnum\x=3
\fill[red] (\x,0) circle (0.2cm);
\else
\fill[blue] (\x,0) circle (0.2cm);
\fi
}

样式定义

定义新样式

% 全局样式
\tikzset{
mynode/.style={
circle,
draw,
fill=blue!20,
minimum size=1cm
},
myarrow/.style={
->,
>=Stealth,
thick,
red
}
}

% 使用样式
\begin{tikzpicture}
\node[mynode] (A) at (0,0) {A};
\node[mynode] (B) at (2,0) {B};
\draw[myarrow] (A) -- (B);
\end{tikzpicture}

带参数的样式

\tikzset{
colored node/.style={
circle,
draw,
fill=#1,
minimum size=1cm
}
}

\node[colored node=red] at (0,0) {红};
\node[colored node=blue] at (2,0) {蓝};

最佳实践

1. 使用相对定位

% 不推荐:绝对坐标难以调整
\node at (0,0) {A};
\node at (2,0) {B};

% 推荐:相对定位便于修改
\node (A) {A};
\node[right=2cm of A] {B};

2. 定义可复用样式

% 在导言区定义样式
\tikzset{
box/.style={rectangle, draw, rounded corners, minimum height=1cm},
arrow/.style={->, thick}
}

% 在文档中使用
\begin{tikzpicture}
\node[box] (a) {A};
\node[box, right=of a] (b) {B};
\draw[arrow] (a) -- (b);
\end{tikzpicture}

3. 合理使用图层

% 背景、内容、前景分层
\begin{tikzpicture}
\begin{scope}[on background layer]
\fill[gray!10] (0,0) rectangle (4,3);
\end{scope}

\node at (2,1.5) {内容};

\begin{scope}[on foreground layer]
\draw[red, thick] (0,0) rectangle (4,3);
\end{scope}
\end{tikzpicture}

常见问题

问题1:图形超出页面

% 使用 scale 调整大小
\begin{tikzpicture}[scale=0.8]
...
\end{tikzpicture}

% 或使用 transform shape 同时缩放节点文字
\begin{tikzpicture}[scale=0.8, transform shape]
...
\end{tikzpicture}

问题2:编译缓慢

% 使用 externalize 缓存
\usetikzlibrary{external}
\tikzexternalize

% 跳过外部化(调试时)
\tikzexternaldisable

问题3:中文节点问题

% 确保加载 ctex
\usepackage{ctex}

% 节点中正常使用中文
\node {中文文本};

小结

本章介绍了 TikZ 绘图的基础知识:

  • 基本绘图\draw 命令和基本形状
  • 样式设置:线条、填充、透明度
  • 坐标系统:笛卡尔坐标、极坐标、相对坐标
  • 节点与标签:节点定义、样式、锚点
  • 箭头与连接:各种箭头样式和节点连接方式
  • 流程图:使用 TikZ 绘制流程图和状态图
  • 函数图像:直接绘图和使用 pgfplots
  • 编程特性:循环、条件、样式定义

TikZ 功能强大,本章仅介绍基础用法。更多高级功能请参考官方文档。

参考资源