PGF/TikZ and Pgfplots

Table of Contents

1. PGF/TikZ 简介

PGF/TikZ 是 Latex 中强大的画图工具(TikZ 基于 pgf)。
pgf stands for Portable Graphics Format. TikZ is a recursive acronym for "TikZ ist kein Zeichenprogramm" (German for "TikZ is not a drawing program").

参考:
A very minimal introduction to TikZ: http://cremeronline.com/LaTeX/minimaltikz.pdf
The TikZ and PGF Packages (Manual): http://mirror.bjtu.edu.cn/CTAN/graphics/pgf/base/doc/pgfmanual.pdf
http://ctan.org/pkg/pgf
http://martin-thoma.com/tag/tikz/
http://www.texample.net/tikz/examples/
https://www.sharelatex.com/learn/Pgfplots_package

1.1. 环境设置

设置 \usepackage{tikz} 后,在 \begin{tikzpicture}\end{tikzpicture} 之间即可编写 PGF/TikZ 代码了。

\documentclass{article}

\usepackage{tikz}
%% \usepackage{pgfplots}  % 使用\begin{axis}需要它
\thispagestyle{empty}
\begin{document}
\begin{tikzpicture}
somethings...
\end{tikzpicture}
\end{document}

上面只是一个最基本的环境设置,对于一些库可能还需要使用 \usetikzlibrary{...} 指令。一些常用的库可参考:http://tex.stackexchange.com/questions/42611/list-of-available-tikz-libraries-with-a-short-introduction

2. 绘制基本图形

下面将演示用 PGF/TikZ 画一些基本图形的方法。

2.1. 直线

\begin{tikzpicture}
\draw (0,0) -- (3,3);
\end{tikzpicture}

上面是画一条直线,如图 1 所示。

tikz_line.svg

Figure 1: TikZ 直线实例

2.2. 虚线([dashed] or [dotted])

\begin{tikzpicture}
\draw [dashed] (0,1) -- (5,1);
\draw [dotted] (0,0.5) -- (5,0.5);
\end{tikzpicture}

效果如图 2 所示。

tikz_dash.svg

Figure 2: TikZ 虚线实例

2.3. 控制线的粗细

可以用 [ultra thick], [very thick], [thick], [thin], [very thin], [ultra thin] 来控制线的粗细,也可以直接用 line width 来控制粗细(默认单位为 pt)。

\begin{tikzpicture}
\draw [ultra thick] (0,2) -- (5,2);
\draw [very thick] (0,1.5) -- (5,1.5);
\draw [thick] (0,1) -- (5,1);
\draw [thin] (0,0.5) -- (5, 0.5);
\draw [dashed, line width=12] (0,0) -- (5, 0);
\end{tikzpicture}

效果如图 3 所示。

tikz_thickness.svg

Figure 3: TikZ 控制线的粗细实例

2.4. 箭头

\begin{tikzpicture}
\draw [->] (0,2) -- (5,2);
\draw [<-] (0,1.5) -- (5,1.5);
\draw [<->] (0,1) -- (5,1);
\draw [dashed, |->] (0,0.5) -- (5, 0.5);
\draw [<-|] (0,0) -- (3, 0) -- (4, -0.5) -- (5,0);
\end{tikzpicture}

效果如图 4 所示。

tikz_arrow.svg

Figure 4: TikZ 控制线的粗细实例

2.5. 矩形、圆等等

\begin{tikzpicture}
\draw [thick] (0,0) rectangle (1.5,1);
\draw (2,0) -- (3.5,0) -- (3.5,1) -- (2,0);
\draw (4.5,0.5) circle [radius=0.5];
\draw (6.5,0.5) circle [x radius=1, y radius=0.5];
\end{tikzpicture}

效果如图 5 所示。

tikz_shape.svg

Figure 5: TikZ 矩形、圆等实例

说明:不用 rectangle ,直接画 4 条线显然也可以画矩形。

2.6. 给某点作标记

如何标记某个点呢?请看下面例子。

\begin{tikzpicture}
\draw [thick, <->] (0,2) -- (0,0) -- (6,0);
\node at (1,1) {$(1,1)$};
\draw [fill] (3,1) circle [radius=1.5pt];
\node [below] at (3,1) {below};
\node [above] at (3,1) {above};
\node [left] at (3,1) {left};
\node [right] at (3,1) {right};
\draw [fill] (5,1) circle [radius=1.5pt];
\node [above right] at (5,1) {$(5,1)$};
\end{tikzpicture}

效果如图 6 所示。

tikz_label.svg

Figure 6: TikZ 给某点作标记

3. Pgfplots 包

The pgfplots package is a powerful tool, based on tikz.

3.1. 实例:画函数 sin(x)的图形

\documentclass{minimal}
\usepackage{pgfplots}

\thispagestyle{empty}
\begin{document}

%%% 第一个图
\begin{tikzpicture}
\begin{axis}
\addplot [] {sin(deg(x))};
\end{axis}
\end{tikzpicture}

%%% 第二个图
\begin{tikzpicture}
\begin{axis} [
    axis x line=center,         % 和下行一起,显示交点在原点的直角坐标
    axis y line=center,
    xlabel = $x$,
    ylabel = {$f(x)$},
    xlabel style={right},
    ylabel style={above},
    xmin = -8,                  % 和下行一起,表示x轴显示范围为 [-8,8]
    xmax = 8,
]
\addplot [
  samples=201,                  % 用更多的样本点(如201个)画图,使图形更平滑。
  domain=-6:6,                  % 在[-6,6]这个区间内画图。
] {sin(deg(x))};
\addlegendentry{$sin(x)$}       % 增加图例。
\end{axis}
\end{tikzpicture}

\end{document}

效果如图 7 所示。

tikz_pgfplots_sin.svg

Figure 7: pgfplots 画 f(x)=sin(x)图形

3.2. 实例:画多个函数和点

\documentclass{minimal}
\usepackage{pgfplots}
\pgfplotsset{compat=1.12}

\thispagestyle{empty}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
    axis x line=center,
    axis y line=center,
    xlabel = $x$,
    ylabel = {$f(x)$},
    xlabel style={right},
    ylabel style={above},
    xmin = -10,
    xmax = 10,
]

%% 画 y=x^2 - 1
\addplot [domain=-9:9] {x^2 - 1};
\addlegendentry{$x^2 - 1$}

%% 画 y=x
\addplot [
    domain=-7:7,
    dashed,
]
{5*x};
\addlegendentry{$5x$}

%% 画一个点
\addplot[
    color=red,
    mark=o,
    ]
    coordinates {
    (1,10)
    };

%% 画三个点
\addplot[
    color=blue,
    only marks,       % 仅显示离散的点,不要连接它们
    mark=x,
    ]
    coordinates {
    (1,-10) (2, -20) (3,-10)
    };
\end{axis}
\end{tikzpicture}
\end{document}

效果如图 8 所示。

tikz_pgfplots_fun.svg

Figure 8: pgfplots 画多个图形

3.3. 实例:展示多个数据文件

\documentclass{minimal}
\usepackage{pgfplots}
\thispagestyle{empty}
\begin{document}

\begin{tikzpicture}
\begin{loglogaxis}[
title=Convergence Plot,
xlabel={Degrees of freedom},
ylabel={$L_2$ Error},
grid=major,
legend entries={$d=2$,$d=3$,$d=4$},
]
\addplot table {tikz_pgfplots_datafiles_d1.dat};
\addplot table {tikz_pgfplots_datafiles_d2.dat};
\addplot table {tikz_pgfplots_datafiles_d3.dat};
\end{loglogaxis}
\end{tikzpicture}

\end{document}

三个数据文件分别为:

$ cat tikz_pgfplots_datafiles_d1.dat
dof l2_err level
5 8.312e-02 2
17 2.547e-02 3
49 7.407e-03 4
129 2.102e-03 5
321 5.874e-04 6
769 1.623e-04 7
1793 4.442e-05 8
4097 1.207e-05 9
9217 3.261e-06 10
$ cat tikz_pgfplots_datafiles_d2.dat
dof l2_err level
7 8.472e-02 2
31 3.044e-02 3
111 1.022e-02 4
351 3.303e-03 5
1023 1.039e-03 6
2815 3.196e-04 7
7423 9.658e-05 8
18943 2.873e-05 9
47103 8.437e-06 10
$ cat tikz_pgfplots_datafiles_d3.dat
dof l2_err level
9 7.881e-02 2
49 3.243e-02 3
209 1.232e-02 4
769 4.454e-03 5
2561 1.551e-03 6
7937 5.236e-04 7
23297 1.723e-04 8
65537 5.545e-05 9
178177 1.751e-05 10

效果如图 9 所示。

tikz_pgfplots_datafiles.svg

Figure 9: pgfplots 展示多个数据文件

注:这个实例摘自 pgfplots manual

3.4. 实例:画离散的点

\documentclass{minimal}
\usepackage{pgfplots}
\thispagestyle{empty}
\begin{document}

\begin{tikzpicture}
\begin{axis}
\addplot[
scatter,
only marks,
point meta=explicit symbolic,
scatter/classes={
a={mark=square*,blue},
b={mark=triangle*,red},
c={mark=o,draw=black}},
]
table[meta=label] {
x y label
0.1 0.15 a
0.45 0.27 c
0.02 0.17 a
0.06 0.1 a
0.9 0.5 b
0.5 0.3 c
0.85 0.52 b
0.12 0.05 a
0.73 0.45 b
0.53 0.25 c
0.76 0.5 b
0.55 0.32 c
};
\end{axis}
\end{tikzpicture}

\end{document}

效果如图 10 所示。

tikz_pgfplots_scatter_plot.svg

Figure 10: pgfplots 画离散的点

注:这个实例摘自 pgfplots manual

4. 绘制函数图形

plot 可以画函数图形,如:

\begin{tikzpicture}
\draw [<->] (0,6) -- (0,0) -- (5,0);
\draw[thick, domain=0:4] plot (\x, {\x + 1)});
\end{tikzpicture}

效果如图 11 所示。

tikz_simplefun.svg

Figure 11: TikZ 画 f(x)=x+1 图形

再看一个画函数图形的例子。

\begin{tikzpicture}[domain=0:4]
\draw[very thin,color=gray] (-0.1,-1.1) grid (3.9,3.9);
\draw[->] (-0.2,0) -- (4.2,0) node[right] {$x$};
\draw[->] (0,-1.2) -- (0,4.2) node[above] {$f(x)$};
\draw[color=red] plot (\x,\x) node[right] {$f(x) =x$};
% \x r means to convert '\x' from degrees to _r_adians:
\draw[color=blue] plot (\x,{sin(\x r)}) node[right] {$f(x) = \sin x$};
\draw[color=orange] plot (\x,{0.05*exp(\x)}) node[right] {$f(x) = \frac{1}{20} \mathrm e^x$};
\end{tikzpicture}

效果如图 12 所示。

tikz_functions.svg

Figure 12: TikZ 画函数图形实例

4.1. 实例:使用“Data Visualization 库”画函数图

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{datavisualization}
\usetikzlibrary{datavisualization.formats.functions}
\thispagestyle{empty}

\begin{document}
\begin{tikzpicture}
\datavisualization[school book axes,
visualize as smooth line]

data [format=function] {
var x : interval [-2:2];
func y = \value x * \value x + 1;
};
\end{tikzpicture}
\end{document}

效果如图 13 所示。

tikz_datavis_example1.svg

Figure 13: TikZ 使用 Data Visualization 画函数图形实例

4.2. 实例:使用“pgfplots 包”绘制数学函数图

\documentclass{minimal}
\usepackage{pgfplots}

\thispagestyle{empty}
\begin{document}
\begin{tikzpicture}
\begin{axis}
\addplot[color=red]{exp(x)};
\end{axis}
\end{tikzpicture}
%Here ends the furst plot
\hskip 5pt
%Here begins the 3d plot
\begin{tikzpicture}
\begin{axis}
\addplot3[
    surf,
]
{exp(-x^2-y^2)*x};
\end{axis}
\end{tikzpicture}
\end{document}

效果如图 14 所示。

tikz_addplot3.svg

Figure 14: TikZ 绘制数学函数图

摘自:https://www.sharelatex.com/learn/Pgfplots_package

5. 其它例子

关于 PGF/TikZ 的更加例子请参考:http://www.texample.net/tikz/examples/

5.1. 实例:绘制神经网络

参考:http://www.texample.net/tikz/examples/neural-network/

\documentclass{article}

\usepackage{tikz}
\begin{document}
\pagestyle{empty}

\def\layersep{2.5cm}

\begin{tikzpicture}[shorten >=1pt,->,draw=black!50, node distance=\layersep]
    \tikzstyle{every pin edge}=[<-,shorten <=1pt]
    \tikzstyle{neuron}=[circle,fill=black!25,minimum size=17pt,inner sep=0pt]
    \tikzstyle{input neuron}=[neuron, fill=green!50];
    \tikzstyle{output neuron}=[neuron, fill=red!50];
    \tikzstyle{hidden neuron}=[neuron, fill=blue!50];
    \tikzstyle{annot} = [text width=4em, text centered]

    % Draw the input layer nodes
    \foreach \name / \y in {1,...,4}
    % This is the same as writing \foreach \name / \y in {1/1,2/2,3/3,4/4}
        \node[input neuron, pin=left:Input \#\y] (I-\name) at (0,-\y) {};

    % Draw the hidden layer nodes
    \foreach \name / \y in {1,...,5}
        \path[yshift=0.5cm]
            node[hidden neuron] (H-\name) at (\layersep,-\y cm) {};

    % Draw the output layer node
    \node[output neuron,pin={[pin edge={->}]right:Output}, right of=H-3] (O) {};

    % Connect every node in the input layer with every node in the
    % hidden layer.
    \foreach \source in {1,...,4}
        \foreach \dest in {1,...,5}
            \path (I-\source) edge (H-\dest);

    % Connect every node in the hidden layer with the output layer
    \foreach \source in {1,...,5}
        \path (H-\source) edge (O);

    % Annotate the layers
    \node[annot,above of=H-1, node distance=1cm] (hl) {Hidden layer};
    \node[annot,left of=hl] {Input layer};
    \node[annot,right of=hl] {Output layer};
\end{tikzpicture}
% End of code
\end{document}

效果如图 15 所示。

tikz_neural_network.svg

Figure 15: TikZ 画神经网络

5.2. 实例:绘制自动机

参考:http://martin-thoma.com/how-to-draw-a-finite-state-machine/

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{arrows,automata}

\thispagestyle{empty}
\begin{document}
\begin{tikzpicture}[>=stealth',shorten >=1pt,auto,node distance=2cm]
  \node[initial,state,accepting] (S)      {$S$};
  \node[state]         (q1) [right of=S]  {$q_1$};
  \node[state]         (q2) [right of=q1] {$q_2$};


  \path[->] (S)  edge [loop above] node {a} (S)
             edge              node {a} (q1)
        (q1) edge [bend left]  node {a} (S)
             edge              node {b} (q2)
        (q2) edge [loop above] node {b} (q2)
             edge [bend left]  node {b} (q1);
\end{tikzpicture}
\end{document}

效果如图 16 所示。

tikz_automata.svg

Figure 16: TikZ 画自动机

Author: cig01

Created: <2015-10-25 Sun>

Last updated: <2017-05-16 Tue>

Creator: Emacs 27.1 (Org mode 9.4)