TikZ는 LaTeX 안에서 직접 코드로 벡터 그래픽을 그리는 표준 시스템입니다. 좌표, 선, 원, 화살표, 노드를 본문과 같은 소스에 쓰면 그림이 본문과 같은 글꼴과 같은 품질로 조판됩니다. 별도의 그림 프로그램을 오갈 필요 없이, 그림이 문서의 재현 가능한 일부가 됩니다. 이것이 이 페이지의 주제입니다.
PGF와 TikZ
먼저 이름을 정리해 봅시다. 바닥에는 PGF (Portable Graphics Format)가 있으며, PDF와 DVI 같은 드라이버 차이를 흡수하면서 실제로 선을 그리는 저수준 그래픽 엔진입니다. 생 PGF를 직접 쓰는 일은 번거롭습니다. 그래서 사람이 편하게 쓸 수 있도록 PGF 위에 얹은 프런트엔드(매크로 층)가 TikZ입니다. 둘 다 Till Tantau가 만들었습니다.
TikZ라는 이름은 독일어 “TikZ ist kein Zeichenprogramm”(“TikZ는 그림 프로그램이 아니다”)의 재귀적 GNU식 약어입니다. 공식 발음은 정해져 있지 않아 /tiks/, /tikts/, /tik-zee/ 등으로 들립니다. 실무에서는 “PGF/TikZ”를 하나로 묶어 말하고, 우리가 실제로 쓰는 것은 거의 항상 TikZ 쪽입니다.
시작은 간단합니다. 프리앰블에 \usepackage{tikz}만 쓰면 PGF도 함께 로드됩니다. pdfLaTeX, LuaLaTeX, XeLaTeX에서는 그대로 사용할 수 있습니다. pLaTeX나 upLaTeX처럼 DVI를 거칠 때만 드라이버(보통 dvipdfmx)를 클래스 옵션으로 지정합니다.
\documentclass{article} % pLaTeX なら \documentclass[dvipdfmx]{jsarticle}
\usepackage{tikz}
\begin{document}
We are working on
\begin{tikzpicture}
\draw (-1.5,0) -- (1.5,0);
\draw (0,-1.5) -- (0,1.5);
\end{tikzpicture}.
\end{document}이는 “We are working on”이라는 본문 뒤에 원점을 지나는 수평선과 수직선, 즉 작은 십자를 같은 줄 안에 그리고 마지막에 마침표를 찍습니다. 그림이 문자와 같은 줄에 자연스럽게 섞이는 것이 TikZ의 느낌입니다.
tikzpicture 환경
모든 그림은 tikzpicture 환경(\begin{tikzpicture} … \end{tikzpicture}) 안에 그립니다. 이것이 한 장의 그림을 담는 “캔버스”이고, 그 안에 그리기 명령을 나열합니다. 환경 이름 뒤의 대괄호에는 그림 전체에 적용되는 옵션을 쓸 수 있습니다(예: [scale=2]는 2배 확대, [thick]은 전체를 두꺼운 선으로).
한 줄짜리 작은 그림이라면 환경을 열 필요 없이 \tikz{...} 또는 명령 하나만 있는 \tikz \draw ...; 같은 인라인 형태로 쓸 수 있습니다. 어느 형태든 절대 잊으면 안 되는 약속이 하나 있습니다. 각 그리기 명령은 세미콜론 ;으로 끝납니다. 세미콜론은 “이 경로는 여기까지”라는 구분이며, 빼먹으면 오류가 납니다. 초보자가 가장 많이 막히는 지점입니다.
% 行内(インライン)
\tikz \draw (0,0) -- (1.5,0);
% 環境(複数のコマンド)
\begin{tikzpicture}
\draw (-1.5,0) -- (1.5,0) -- (0,-1.5) -- (0,1.5);
\end{tikzpicture}경로 모델 — 좌표와 경로 조작
TikZ 그리기는 경로(path)를 중심으로 이루어집니다. 경로란 “점에서 점으로 어떻게 이동할지”를 쓴 길이며, 그것을 어떻게 보일지는 명령 이름으로 선택합니다. \draw는 경로를 선으로 긋고, \fill은 닫힌 경로의 내부를 채우며, \filldraw는 채운 뒤 외곽선도 그리고, \path는 나중에 참조할 좌표나 노드를 놓을 때처럼 아무것도 그리지 않고 경로만 정의합니다.
점을 지정하는 좌표에는 세 가지가 있습니다. 직교 좌표 (x,y)는 기본 단위가 센티미터라서 (1,2)는 오른쪽 1 cm, 위쪽 2 cm를 뜻합니다. (1cm,2pt)처럼 단위를 명시할 수도 있습니다. 극좌표 (angle:radius)는 (30:1cm)처럼 “30도 방향으로 1 cm”를 뜻합니다. 그리고 좌표에 이름을 붙여 두면(이름 있는 좌표) 나중에 이름으로 불러올 수 있습니다. 상대 지정도 가능해서 ++(1,0)은 현재 위치에서 오른쪽으로 1 cm 이동하고 현재 위치도 갱신하지만, +(1,0)은 갱신 없이 기준점에 대한 상대 위치만 나타냅니다.
경로 조작은 경로가 어떻게 진행되는지를 정합니다. --는 직전 점에서 다음 점까지 직선을 그립니다((a) -- (b)처럼 이어 씁니다). rectangle은 두 대각점으로 사각형을, circle은 중심 기준 원을, ellipse는 타원을, arc는 원호를, grid는 격자를 만듭니다. 곡선은 .. controls ..(Bézier 곡선)나 뒤에서 볼 to[bend]로 그립니다. 닫힌 도형을 만들려면 끝에 -- cycle을 붙여 시작점으로 돌아갑니다.
도형의 인수는 요즘 대괄호 [...] 안의 key-value 쌍으로 넘기는 것이 일반적입니다. 원은 circle [radius=10pt], 타원은 ellipse [x radius=20pt, y radius=10pt], 원호는 arc [start angle=0, end angle=30, radius=3mm](0도부터 30도까지, 반지름 3 mm)처럼 씁니다. grid에는 [step=.5cm]로 간격을 지정합니다. 다음 예는 옅은 격자 위에 원점 중심, 반지름 1 cm의 원과 원점에서 (1,1)로 가는 직선을 그립니다.
\begin{tikzpicture}
\draw[step=.5cm, gray, very thin] (-1.4,-1.4) grid (1.4,1.4);
\draw (0,0) circle [radius=1cm];
\draw (0,0) -- (1,1);
\fill[blue!20] (0,0) rectangle (0.5,0.5);
\end{tikzpicture}이 그림은 (-1.4,-1.4)에서 (1.4,1.4)까지 0.5 cm 간격의 옅은 회색 격자를 배경으로 깔고, 그 위에 원점 중심의 원, 원점에서 오른쪽 위 (1,1)로 가는 대각선, 그리고 원점에서 0.5 cm 정사각형을 옅은 파란색으로 채운 것을 겹친 것입니다. blue!20은 “파랑 20%”, 즉 흰색과 섞인 연한 파랑을 뜻합니다.
노드 — 문자와 도형 놓기
노드(node)는 지정한 좌표에 문자나 도형을 놓는 장치로, 그림에 라벨을 붙일 때 핵심입니다. 기본형은 \node[options] (name) at (coordinate) {contents};입니다. 옵션에는 draw(테두리 그리기), circle이나 rectangle(모양), fill=blue!20(채우기) 등이 들어갑니다. 괄호 안의 name이 이 노드의 핸들이 되어 나중에 (name)이나 (name.north)처럼 위치를 참조할 수 있습니다.
실무에서 자주 쓰는 패턴은 먼저 이름 있는 노드를 놓고, 그다음 이름끼리 선으로 연결하는 것입니다. 좌표를 직접 쓰는 대신 노드 이름으로 잇기 때문에 배치를 바꿔도 선이 자동으로 따라갑니다.
\begin{tikzpicture}
\node (a) at (0,0) [draw, circle, fill=blue!20] {A};
\node (b) at (2.5,0) [draw, circle, fill=blue!20] {B};
\draw[->] (a) -- (b);
\end{tikzpicture}이 그림은 연한 파란색으로 채운 원형 노드 “A”와 “B”를 2.5 cm 떨어뜨려 놓고, A에서 B로 화살표가 붙은 직선을 그립니다. 선은 원 안으로 파고들지 않고 노드의 테두리에서 자연스럽게 멈춥니다.
노드는 경로의 중간에도 놓을 수 있습니다. \draw (a) -- (b) node[midway] {label};처럼 쓰면 a에서 b로 가는 선의 중점(midway)에 라벨이 올라갑니다. above나 below를 더하면 선 위아래로 옮길 수 있습니다. 선에 설명을 붙일 때 표준적인 방식입니다.
옵션과 스타일
선의 모양은 대괄호 안의 옵션으로 세밀하게 조절합니다. 자주 쓰는 것은 두께 thin / thick / very thick, 색 red나 blue!50, 파선 dashed와 점선 dotted, 모서리 둥글림 rounded corners, 그리고 화살표입니다. 화살표는 ->(끝에 화살촉), <-(시작에 화살촉), <->(양끝)입니다. 사실 TikZ는 -를 포함한 알 수 없는 옵션을 모두 화살표 지정으로 해석하는 실용적인 설계를 택합니다.
| 옵션 | 의미 |
|---|---|
thick / very thick | 선을 굵게(ultra thick까지 있음) |
red, fill=blue!50 | 선 색이나 채우기 색(!n으로 농도 지정) |
dashed / dotted | 파선 또는 점선 |
rounded corners | 경로의 모서리를 둥글게 |
->, <-, <-> | 끝, 시작, 양끝의 화살촉 |
scale=2 | 그 그림(또는 경로)을 2배로 확대 |
같은 장식을 여러 번 쓴다면 스타일로 이름을 붙여 재사용하는 것이 정석입니다. 프리앰블에서 \tikzset{name/.style={...}}로 정의하거나, tikzpicture 옵션에서 그 자리에서 정의할 수 있습니다. 예를 들어 다음은 help lines라는 스타일을 정의하고 격자에 적용합니다.
\tikzset{help lines/.style={color=blue!50, very thin}}
\begin{tikzpicture}
\draw[help lines] (0,0) grid (3,2);
\draw[thick, red, ->, rounded corners] (0,0) -- (1,2) -- (3,2);
\end{tikzpicture}이 그림은 (0,0)에서 (3,2)까지 옅은 파란 격자를 그리고, 그 위에 원점에서 (1,2), 다시 (3,2)로 꺾이는 빨간 굵은 선을 그리며, 꺾인 모서리를 둥글게 하고 끝에 화살촉을 붙입니다. 스타일로 만들어 두면 very thin을 thin으로 바꾸는 것만으로 격자 전체의 모양을 한곳에서 바꿀 수 있습니다.
라이브러리 — 필요한 기능 불러오기
TikZ 본체는 의도적으로 작게 유지되고, 전문 기능은 라이브러리로 나뉘어 있습니다. 프리앰블에서 \usetikzlibrary{...}로 필요한 것만 불러옵니다(여러 개는 쉼표로 구분). 자주 쓰는 것은 다음과 같습니다.
arrows.meta— 풍부하고 조정 가능한 화살촉 모음(-{Stealth},-{Latex}등). 예전arrows라이브러리는 권장되지 않으며 지금은 이것을 씁니다.positioning— 노드의 상대 배치.right=of a,below=1cm of b처럼 쓸 수 있습니다.calc— 좌표 계산.($(a)+(1,0)$)은 “a의 오른쪽 1 cm”,($(a)!0.5!(b)$)는 “a와 b의 중점”입니다.shapes— 원과 사각형을 넘어선 다양한 노드 모양(마름모, 별, 말풍선 등).shapes.geometric등으로 세분됩니다.decorations— 경로를 물결, 지그재그, brace 등으로 장식합니다(decorations.pathmorphing등).patterns— 해칭(선이나 점) 같은 패턴으로 채웁니다.fit— 여러 노드를 둘러싸는 상자를 자동으로 만듭니다.backgrounds— 그림 뒤의 배경 레이어에 테두리나 바탕을 그립니다.matrix— 노드를 격자(행렬) 형태로 정렬합니다.graphdrawing은 자동 레이아웃을 수행합니다(LuaTeX 필요).
다음 예는 arrows.meta와 positioning을 조합한 작은 플로차트입니다. 첫 노드에만 좌표를 주고, 나머지는 “오른쪽”, “아래” 같은 상대 지정으로 배치하며, Stealth형 화살촉으로 연결합니다.
\usepackage{tikz}
\usetikzlibrary{arrows.meta, positioning}
\begin{tikzpicture}[node distance=1cm, every node/.style={draw, rounded corners}]
\node (start) {Start};
\node (proc) [right=of start] {Process};
\node (end) [right=of proc] {End};
\draw[-{Stealth}] (start) -- (proc);
\draw[-{Stealth}] (proc) -- (end);
\end{tikzpicture}이 그림은 왼쪽에서 오른쪽으로 흐르는 플로차트가 됩니다. 둥근 모서리 상자 노드 “Start”, “Process”, “End”가 1 cm 간격으로 놓이고, 날카로운 Stealth 화살촉으로 순서대로 연결됩니다. 핵심은 every node/.style로 모든 노드에 공통 모양을 한꺼번에 지정한다는 점입니다.
컴파일 비용과 externalize
TikZ 그림은 LaTeX가 요소 하나하나를 계산해 그리기 때문에, 복잡한 그림이나 그림이 많은 문서는 컴파일이 눈에 띄게 느려집니다. 특히 플롯과 촘촘한 격자는 무거워지기 쉽습니다.
표준 대책은 externalize 라이브러리입니다. \usetikzlibrary{external}를 불러오고 \tikzexternalize를 선언하면 각 tikzpicture를 한 번만 별도의 PDF로 컴파일해 캐시합니다. 이후 실행에서는 그림 내용이 바뀌지 않았다면 TikZ가 계산을 건너뛰고 완성된 PDF만 포함합니다. 첫 실행은 느리지만 이후 편집 주기는 크게 빨라집니다(그림을 고치면 자동으로 다시 생성됩니다). 또는 큰 그림을 별도 파일로 나누고 standalone 클래스로 단독 컴파일할 수도 있습니다.