tikz 折线 箭头_[LaTeX 绘图] tikz 绘制流程图,概述和两个示例
本文已加入專欄文章目錄,歸入「示例」文章系列。
流程圖,或者類似流程圖的繪圖目標,主要指具有以下特征的圖形組合:多個帶框文本,框的形狀、框之間的位置關系有規律
多條帶箭頭的線,線連接框
(這里是想說,在具體的使用場景和學科背景下,圖形們各有各的叫法和名字,但從繪圖的角度,它們和本文所介紹的「流程圖」有很大的共性。)
以下,在無明顯歧義時,我們用 node 代指「帶框文本」,用 arrow 代指「帶箭頭的線」。
在 tikz 文檔的 Tutorials 中,有Sec. 3 Tutorial: A Petri-Net for Hagen和
Sec. 5 Tutorial: Diagrams as Simple Graphs
兩個流程圖繪制的例子。本文提及的大部分內容,都能在這兩個官方文檔示例中找到介紹。
引入例子
一個簡陋的例子
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning, shapes.geometric}
\begin{document}
\begin{tikzpicture}[node distance=10pt]
\node[draw, rounded corners] (start) {Start};
\node[draw, below=of start] (step 1) {Step 1};
\node[draw, below=of step 1] (step 2) {Step 2};
\node[draw, diamond, aspect=2, below=of step 2] (choice) {Choice};
\node[draw, right=30pt of choice] (step x) {Step X};
\node[draw, rounded corners, below=20pt of choice] (end) {End};
\draw[->] (start) -- (step 1);
\draw[->] (step 1) -- (step 2);
\draw[->] (step 2) -- (choice);
\draw[->] (choice) -- node[left] {Yes} (end);
\draw[->] (choice) -- node[above] {No} (step x);
\draw[->] (step x) -- (step x|-step 2) -> (step 2);
\end{tikzpicture}
\end{document}
上述例子中,故意略去了關于 node 的設置,如外框形狀
關于 arrow 的設置,例如線的樣式、箭頭的樣式等
關于顏色和字體的設置
這些都可以通過定義 tikz style 來解決。
上述例子中,值得關注的是這些:少用、甚至不用具體坐標第一個 node 省略了坐標,相當于指定了 (0, 0)
從第二個 node 開始,利用 tikz library positioning 提供的選項(例如 below=of ), 指定相對位置關系。
效果是,每組 node,外框之間的(最小)距離都相同,是 node distance 指定的 10pt;在需要手動調整距離時,可以使用right= of 。
繪制 arrow 時,完全使用 node name
在繪制 arrow 時一并輸入 arrow 周圍的文字標注
配合設置好的 tikz style,這已經是一個功能完整、可以接受的流程圖繪制方式了。這種繪制方式,在 tikz 文檔 Sec. 3 和 Sec. 5 里也能見到,但文檔中的例子沒有止步于此。
簡化 arrow 的輸入
例子中,繪制 arrow 用了一半的輸入行,而我們需要的不過是一串首尾相接的 arrow,例如 (start) -> (step 1) -> (step 2) -> (choice) -> (end)。
\graph 命令就接受這樣的輸入。(輸出效果同上,不重復貼圖)
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{graphs, positioning, quotes, shapes.geometric}
\begin{document}
\begin{tikzpicture}[node distance=10pt]
\node[draw, rounded corners] (start) {Start};
\node[draw, below=of start] (step 1) {Step 1};
\node[draw, below=of step 1] (step 2) {Step 2};
\node[draw, diamond, aspect=2, below=of step 2] (choice) {Choice};
\node[draw, right=30pt of choice] (step x) {Step X};
\node[draw, rounded corners, below=20pt of choice] (end) {End};
\graph{
(start) -> (step 1) -> (step 2) -> (choice) ->["Yes"left] (end);
(choice) ->["No"] (step x) ->[to path={|- (\tikztotarget)}] (step 2);
};
\end{tikzpicture}
\end{document}
注意到新加載了兩個 tikz librarylibrary graph,用于提供 \graph 命令
library quotes,將 node label 的輸入從 label={[]} 簡化為 ""
雖然 (start) -> (step 1) -> (step 2) -> (choice) -> (end) 的語法大大簡化了輸入,但是標記 node label 和繪制非簡單 arrow 變麻煩了,帶來了學習成本
如果使用了選項 use existing nodes=true,輸入(start) -> (step 1) -> (step 2) 能進一步簡化為 start -> step 1 -> step 2。
tikz 文檔 Sec. 5.4.1 就介紹了這種繪制方式:帶框文字用 \node 結合 tikz library positioning
帶箭頭的線用 \graph 結合 tikz library quotes
其他可選的方案帶框文字用 \node 結合 tikz library positioning,帶箭頭的線用操作符 edge。這是 tikz 文檔 Sec.3 的最終狀態
優勢:代碼結構清晰,額外學習成本低
劣勢:每條線對應一個 edge,線多時仍然麻煩
用 \graph 同時處理兩件事。這是 tikz 文檔 Sec. 5 的最終狀態
優勢:線的標記十分輕量
劣勢:一定的額外學習成本,包括;
兩件事同時做,代碼可讀性降低;
圖的生長方向由代碼自動決定,如需 100% 控制圖的最終效果,手動調整不可少
用 \matrix 處理框的相對位置這是 tikz 文檔 Sec. 5.3 的狀態
優勢:配合 tikz library matrix 的 matrix of nodes 選項,在某些情況下能大幅簡化 node 的輸入
具體例子 1,\matrix 配合 tikz library chains
注意,示例只是說明「在這種情況下,可以這么做」,不傳遞類似「這是最佳操作」的信息。
實際使用中,應結合圖形特征和自己的 tikz 知識,決定使用的輸入方式。
繪圖的首要目的是「能畫出來」,資源允許時兼顧輸入的優雅。
忽略 tikz style 的定義,只看例 1 中 tikzpicture 環境內容的輸入方式和輸出效果。
\begin{tikzpicture}
%% upper nodes \matrix (m1) [upper matrix] {
|[box 1=01000000]| sentry &
|[box 1=01000001]| 2 &
|[box 1=01001001]| 18 &
|[box 2=11000000]| sentry &
|[box 2=11000001]| 3 &
|[box 2=11010001]| 11 &
|[box 2=11011001]| 27 \\
};
%% chain \begin{scope}[start chain]
\foreach \i in {1, ..., 7} {
\chainin (m1-1-\i);
}
\end{scope}
%% lower nodes \matrix (m2) [at=(m1-1-3), lower matrix] {
0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\
};
%% curving arrows \draw[loose arrow=0.6, out=120, in=-50] (m2-1-3.north) to (m1-1-1.south);
\draw[arrow, out=90, in=-105] (m2-1-4.north) to (m1-1-4.south);
\end{tikzpicture}
解釋說明:上下分成兩個 \matrix 進行輸入,上方 \matrix 的特征是,每個 node 頂部都有 node label,這里以選項參數的形式輸入 node label text
matrix of nodes 模式下,每個 node 的參數可通過 |[]| 輸入
帶箭頭的線可分為兩類連接(上方 \matrix)相鄰 node 的直線。因為 matrix 中的 node name 有規律,這里借助 tikz library chains,以循環的方式適當簡化輸入
連接上下方 node 的曲線。每條曲線對應一根三次貝塞爾曲線。
這里通過選項 in 和 out 控制曲線出發和到達時的角度,再通過選項 looseness 控制曲線的「彎曲程度」。
這三個選項的綜合效果,和直接調整貝塞爾曲線的控制點不等價;在額外使用選項 in control 和 out control 后,能等價。
例 1 有一個變體。主要變化是,在下方 \matrix 中通過使用 set color= 改變之后所有 nodes 的填充色,適當簡化下方 \matrix 的輸入。
%% lower nodes \matrix (m2) [below right=30pt and -10pt of m1-1-3, lower matrix] {
0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 &
|[set color=DodgerBlue3]| 10 & 11 & 12 & 13 & 14 & 15 \\
};
最后,看一眼例 1 的 tikz style 部分
% \PassOptionsToPackage{x11names}{xcolor}
\usetikzlibrary{
arrows.meta,
chains,
matrix,
positioning,
}
\makeatletter
\def\@currentColor{white}
\tikzset{
set color/.code = { \gdef\@currentColor{#1} },
%% node box/.style = {
draw,
rounded corners=2mm,
minimum width=4.5em,
minimum height=2em,
font=\color{white}\ttfamily,
text height=1.5ex,
text depth=.25ex,
label={[black]above:#1},
},
box 1/.style = {box=#1, fill=orange},
box 2/.style = {box=#1, fill=cyan},
box 3/.style = {box=#1, fill=yellow!80!red},
lower box/.style = {
draw,
fill=\@currentColor,
minimum height=2.5em,
inner xsep=2pt,
font=\color{white}\ttfamily
},
%% matrix matrix default/.style = {
matrix of nodes
},
upper matrix/.style = {
matrix default,
column sep=15pt
},
lower matrix/.style = {
matrix default,
column sep=0pt,
set color=Green3, % set default color before key "lower box" is passed nodes=lower box
},
%% arrow arrow/.style = {
arrows={ -Triangle[angle=45:2.5pt 3] },
line width=1pt
},
%% chain every on chain/.style = {
join=by arrow
},
}
\makeatother
值得一看的是box/.style 的部分,展示了設置「固定寬高的 node」常用的選項
arrow/.style 的部分,展示了通過 arrows 選項指定箭頭樣式的方式
具體例子 2,edge 與 node 分離,tikz libraryfit
本例中,值得一看的是node 允許包含多行文本時,如何控制文本的最大寬度和對齊方式
使用單獨的 \path 命令,通過 edge 集中繪制帶箭頭的線(能簡化為 \graph)
使用 tikz library fit 繪制「包含若干個 node 的矩形」 ,避免使用具體坐標
其他技巧還涉及利用坐標運算,使得通過 fit 繪制的矩形,關于包含的 nodes 左右對稱
(因為 edge 的 node label 偏向右側的緣故,如果矩形只是 "fit" nodes 和 node labels,矩形看起來會偏右。)
允許指定增加值,以「讓某個 node 更高和更寬一些」,免去記憶默認高寬,簡化輸入
示例源碼tikz-example-flowchart1.* 和
tikz-example-flowchart2.*
(注:不包含簡陋示例)
總結
以上是生活随笔為你收集整理的tikz 折线 箭头_[LaTeX 绘图] tikz 绘制流程图,概述和两个示例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python列表的“增删改查”(pyth
- 下一篇: 分治算法求解棋盘覆盖问题