在寫作論文時,流程圖是一種最為直覺和直接的方法來幫助我們表示思想方法或者算法。下面介紹一種使用 LaTeX 宏包 TikZ 來繪制矢量流程圖的方法,主要參考了這篇部落格 Ethan Deng
基本步驟
下面給出一個基本框圖的代碼,請注意注釋:
% texlive2015, pdflatex
\documentclass{article}
\usepackage{palatino}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric, arrows}
\begin{document}
\thispagestyle{empty}
% 流程圖定義基本形狀
\tikzstyle{startstop} = [rectangle, rounded corners, minimum width = 2cm, minimum height=1cm,text centered, draw = black]
\tikzstyle{io} = [trapezium, trapezium left angle=70, trapezium right angle=110, minimum width=2cm, minimum height=1cm, text centered, draw=black]
\tikzstyle{process} = [rectangle, minimum width=3cm, minimum height=1cm, text centered, draw=black]
\tikzstyle{decision} = [diamond, aspect = 3, text centered, draw=black]
% 箭頭形式
\tikzstyle{arrow} = [->,>=stealth]
\begin{tikzpicture}[node distance=2cm]
%定義流程圖具體形狀
\node[startstop](start){Start};
\node[io, below of = start, yshift = -1cm](in1){Input};
\node[process, below of = in1, yshift = -1cm](pro1){Process 1};
\node[decision, below of = pro1, yshift = -1cm](dec1){Decision 1 ?};
\node[process, below of = dec1, yshift = -1cm](pro2){Process 2};
\node[io, below of = pro2, yshift = -1cm](out1){Output};
\node[startstop, below of = out1, yshift = -1cm](stop){Stop};
\coordinate (point1) at (-3cm, -6cm);
%連接配接具體形狀
\draw [arrow] (start) -- (in1);
\draw [arrow] (in1) -- (pro1);
\draw [arrow] (pro1) -- (dec1);
\draw (dec1) -- node [above] {Y} (point1);
\draw [arrow] (point1) |- (pro1);
\draw [arrow] (dec1) -- node [right] {N} (pro2);
\draw [arrow] (pro2) -- (out1);
\draw [arrow] (out1) -- (stop);
\end{tikzpicture}
\end{document}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
編譯出來的效果:

當然你也可以做得 Fancy 一點,比如下面這個模拟退火算法的框圖:
其代碼如下:
% texlive2015, pdflatex
\documentclass{standalone}
\usepackage{newtxmath}
\usepackage{palatino}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric, arrows}
\begin{document}
\thispagestyle{empty}
% 流程圖定義基本形狀
\tikzstyle{startstop} = [rectangle, rounded corners, minimum width = 2cm, minimum height=1cm,text centered, draw = black, fill = red!40]
\tikzstyle{io} = [trapezium, trapezium left angle=70, trapezium right angle=110, minimum width=2cm, minimum height=1cm, text centered, draw=black, fill = blue!40]
\tikzstyle{process} = [rectangle, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill = yellow!50]
\tikzstyle{decision} = [diamond, aspect = 3, text centered, draw=black, fill = green!30]
% 箭頭形式
\tikzstyle{arrow} = [->,>=stealth]
\begin{tikzpicture}[node distance=2cm]
%定義流程圖具體形狀
\node (start) [startstop]
{Start};
\node (in1) [io, below of = start]
{Initial $x_0=(x_{01},x_{02},\cdots)$};
\node (pro1) [process, right of = in1, xshift = 5cm]
{Calculation $u_0=f(x_0)$};
\node (pro4) [process, below of = in1]
{New result $u^*=f(x_0^*)$};
\node (pro3) [process, below of=pro1]
{New solution $x_0^*=(\cdots,x_{0i},\cdots$)};
\node (pro2) [process, right of=pro3, xshift = 4cm]
{Randomly change $x_0$ into $x_0^*$};
\node (dec1) [decision, below of=pro4]
{Optimized?};
\node (pro5) [process, below of=pro3]
{Accept new solution probobly};
\node (pro6) [process, below of=dec1]
{Accept new solution};
\node (dec2) [decision, below of=pro5]
{Enough iterations?};
\node (pro7) [process, below of=dec2]
{Accept new solution as optimized solution};
\node (out1) [io, below of=pro6]
{Output $x_0^*$};
\node (stop) [startstop, below of=out1]
{stop};
%連接配接具體形狀
\draw [arrow] (start) -- (in1);
\draw [arrow] (in1) -- (pro1);
\draw [arrow] (pro1) -| (pro2);
\draw [arrow] (pro2) -- (pro3);
\draw [arrow] (pro3) -- (pro4);
\draw [arrow] (pro4) -- (dec1);
\draw [arrow] (dec1) --node [above] {N} (pro5);
\draw [arrow] (dec1) --node [right] {Y} (pro6);
\draw [arrow] (pro6) -- (dec2);
\draw [arrow] (pro5) -- (dec2);
\draw [arrow] (dec2) -|node [right] {N} (pro2);
\draw [arrow] (dec2) --node [right] {Y} (pro7);
\draw [arrow] (pro7) -- (out1);
\draw [arrow] (out1) -- (stop);
\end{tikzpicture}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
當然 LaTeX 是支援自定義顔色的,如果你有一套非常優秀的顔色配比,相信你可以畫出非常好看的流程圖。
總結
用 LaTeX 可以畫出矢量的流程圖,重點是在變成之前先安排好各個流程的位置。
如果你用 LaTeX 寫論文的話會發現,這是一種使用其他軟體生成的 jpg 格式圖檔所不能比拟的優勢。另外,在PowerPoint 中使用“插入形狀”并選擇儲存為 pdf 格式也可以得到矢量的 pdf 檔案來插入到 LaTeX 的寫作當中,不過這裡不讨論這種所見即所得的方法。
彩蛋:使用 markdown 編輯器作流程圖
第一次在 CSDN 上寫部落格時,我知道了可以使用 markdown 編輯器作流程圖,效果也是不錯的。代碼如下:
```mermaid
flowchat
st=>start: 開始
e=>end: 結束
op=>operation: 操作
cond=>condition: 确認?
st->op->cond
cond(yes)->e
cond(no)->op
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
可以看到,markdown 文法可以直接畫出否認和操作的有兩個直角的連線,比 LaTeX 要友善一些。
更多關于 markdown 流程圖 的文法,可以參考這裡。