低分子量有機塩素化合物

航空宇宙工学科の学生です.

今日から使える,レポートのためのTikZ入門

はじめに

この記事は東京大学航空宇宙工学科/専攻 Advent Calendar 2019の4日目の記事です。

はじめまして。東京大学航空宇宙工学科B3のLMCHといいます。よろしくお願いします。
さて,12月となり航空宇宙工学科B3は年内提出の大量の課題に追われているところです。今回はそのレポートたちにも関係する,\TeX用の描画パッケージであるTikZ/PGFについて紹介していきます。目標は,TikZを全く知らない人がとにかく何でもいいから図を描けるようになること,です。

対象読者

以下の条件に当てはまる人を想定しています。

  • 前提:\LaTeXでレポートを書いている人。
  • レポートに貼る図を美しくしてみたい人。
  • TikZをまだ使ったことがないという人。

課題に貼る図を美しくしたい人,どれだけ居るのだろうか...

TikZ/PGFとは

PGF is a macro package for creating graphics. It is platform- and format-independent and works together with the most important TEX backend drivers, including pdfTEX and dvips. It comes with a user-friendly syntax layer called TikZ.[1]

という訳で,簡単に言えば\TeXでの描画パッケージがPGFであり,PGFを扱うマクロのようなものがTikZであるというような理解でいいかと思います。

少なくとも,この記事の範囲ではTikZを利用した図の描画を目標としているので以降は単にTikZと呼ぶことにします。ちなみに,"TikZ"は「てぃくす」と発音されることが多いようです。[2]

なぜTikZなのか

どうしてTikZを使うのか,という疑問について僕が思い浮かんだTikZの特徴を並べてみました。

  • コマンドで手軽に図を描画できる。
  • 文章本体と図が\TeXの環境内で完結する。

コマンド上で描画を行うことで,細かい座標の指定をしたりforeach文を回して同じ図形を何個も生成したりすることが手軽に行えるのはやはり便利だと思います。そのため,多くのノードとエッジからなるグラフの作成にはかなり強かったりします。また,\TeXの環境内なので数式などを自然に美しく図中に挿入できるのもスマートですね。

早速描いてみよう

今回の目標は以下の簡単な図を描くことにとしましょう。イメージとしては座標回転の式を導出したいときに貼る図,といったところでしょうか。パワポなどでこういった図を作るの,意外と面倒だったりしますよね。 f:id:LMCH:20191203010031p:plain

それでは,早速TikZを使い始めるためにパッケージを読み込みましょう。pTeX系のDVI出力のエンジンを使用している際はドライバの指定が必要です。

%プリアンブルに記述
%\usepackage[dvipdfmx]{graphicx,xcolor} %pLaTeXやupLaTeXの場合は必要
\usepackage{tikz}
\usetikzlibrary{arrows}%矢印を描画するための設定に必要

TikZの命令はtikzpicture環境内に書きますが,\centeringして中央に配置したり,キャプションやラベルを付けたりすることを考えた場合figure 環境内にtikzpicture環境を用意するのが手っ取り早いです。試しに座標軸を描いてみましょう。

\begin{figure}[t]
  \centering
  \begin{tikzpicture}
    %ここから描画コマンド
    \draw[->](-1,0) -- (4,0);%x軸
    \draw[->](0,-1) -- (0,4);%y軸
    %ここまで描画コマンド
  \end{tikzpicture}
  \caption{xy座標系とXY座標系の関係図。}
  \label{fig:rotate_xy_to_XY}
\end{figure}

実行結果は以下の通り。

f:id:LMCH:20191203011249p:plain

\drawという命令が出てきました。(本当は\path[draw]という命令の略記ですが,)ここで扱う最も基本的な命令です。\draw (座標1)--(座標2);という文で,座標1と座標2を結ぶ線分を描画することができます。これにオプションとして[->]をつけてやることで矢印になります。ちなみに,細かいですが

  • TikZの命令は文末にセミコロンが必要。
  • TikZの座標は1が1[cm]に対応する。

といった注意点があったりします。特に文末のセミコロンは忘れやすいので注意しましょう。

矢印の修正

さきほど描いた図ですが,どうも矢印が座標軸っぽくない感じがします。もう少し座標軸らしくするために,矢尻の形を以下のように修正してみます(描画コマンド部のみ抜粋)。

%ここから描画コマンド
    \draw[arrows=-{stealth[]}](-1,0) -- (4,0);%x軸
    \draw[arrows=-{stealth[]}](0,-1) -- (0,4);%y軸
%ここまで描画コマンド

こうすることで以下のように修正されます。

f:id:LMCH:20191203022052p:plain

細かいですが,矢尻の形がステルス機型になり,見た目もそれらしくなりました。実際には,すべての矢印でこれを書いていると面倒なのでプリアンブル部に\usetikzlibrary{arrows}を書き足し,tikzpicture環境を呼び出す際にオプションに[>=stealth']を加えることですべての矢尻がステルス機型になります。

因みに,TikZ/PGFのマニュアル[3]は矢印の表現だけで1章が構成されており,30ページ以上にわたる矢印の説明があったりして奥が深いです。TikZに限らず,\TeXのドキュメントの分量は読んでいて面白いので暇な方は是非読んでみてください。

ノードの設定

座標軸の名前xy,また原点Oがないと座標平面になりませんね。という訳で,ここではノードを設定してラベルを貼ります。ノードも奥が深いのですが,ここでは細かいことをすっ飛ばして簡単に説明すると「点に名前を付けること」になると思います。ここでは点の名前を表示させるためにノードを設定します。ここまでまとめて,以下のようになります。

\begin{figure}[H]
  \centering
  \begin{tikzpicture}[>=stealth']%矢尻の形の設定
    %ここから描画コマンド
    \draw[->](-1,0) -- (4,0) node[right]{$x$};%x軸
    \draw[->](0,-1) -- (0,4) node[above]{$y$};%y軸
    \filldraw [black] (0,0) circle (0.5mm);%原点
    \coordinate (O) at (0,-0.1) node at (O) [below left] {$O$};%原点のラベル
    %ここまで描画コマンド
  \end{tikzpicture}
  \caption{xy座標系とXY座標系の関係図。}
  \label{fig:rotate_xy_to_XY}
\end{figure}

結果は以下の通り。

f:id:LMCH:20191203025610p:plain

良い感じですね。ノードはそれ自体に大きさがあるので,ノードで座標を指定すると実際には指定した座標からずれます。それを嫌う場合は\coodinateを用いて座標を指定します。ここでは,後のことを見越して原点Oのラベルを少しy軸負方向にずらして表示させました。また,\filldrawを用いることで図形を描きながらその中を塗ることが可能です。

回転後の座標系の追加

これまでと同じ調子で,回転後の座標系も書き加えてしまいましょう。描画コマンドの部分に,以下の文を書き加えます。

    \draw[->,thick](-1.732/2,-1/2) -- (4*1.732/2,4/2) node[above right]{$X$};%X軸
    \draw[->,thick](1/2,-1.732/2) -- (-4/2,4*1.732/2) node[above left]{$Y$};%Y軸
    \draw[dashed](0,0) -- (3/2,3*1.732/2);
    \filldraw [red] (3/2,3*1.732/2) circle (0.5mm) node[right]{$\bm{r}$};%点r

座標軸を30度回転させるということを想定して\sqrt{3}を1.732で代用して座標は計算させています(もう少しいいやり方がありそうですね...)。また,\drawにさまざまなオプションがついていますが,結果はおおむね予想がつくと思います。実際には以下のようになるはずです。

f:id:LMCH:20191203031945p:plain

弧の追加~完成

最後に,座標軸の回転角を書き加えるために弧を描きます。以下のように書くのが何をやっているか分かりやすいと思います。

 \draw [->](1.5,0) arc [start angle = 0, end angle = 30, radius = 1.5];%半径1.5の弧
 \draw [->](0.8,0) arc [start angle = 0, end angle = 60, radius = 0.8];%半径0.8の弧

一般に,円弧の記述は(開始点の座標) arc [start angle = 開始角, end angle = 終了角, radius = 半径]となります。以上の命令を書き加えて描画すると以下のようになるはずです。

f:id:LMCH:20191203103350p:plain

もうほとんど完成ですね。なお,慣れてきたら同じものを

 \draw [->](1.5,0) arc (0:30:1.5);%半径1.5の弧
 \draw [->](0.8,0) arc (0:60:0.8);%半径0.8の弧

と略記することで手間が省けます。最後に,弧の開始点にラベルを設定し,角度を表示させましょう。完成したコードは以下の通りになります。

\begin{figure}[t]
  \centering
  \begin{tikzpicture}[>=stealth']%矢尻の形の設定
    %ここから描画コマンド
    \draw[->](-1,0) -- (4,0) node[right]{$x$};%x軸
    \draw[->](0,-1) -- (0,4) node[above]{$y$};%y軸
    \filldraw [black] (0,0) circle (0.5mm);%原点
    \coordinate (O) at (0,-0.1) node at (O) [below left] {$O$};%原点のラベル
    \draw[->,thick](-1.732/2,-1/2) -- (4*1.732/2,4/2) node[above right]{$X$};%X軸
    \draw[->,thick](1/2,-1.732/2) -- (-4/2,4*1.732/2) node[above left]{$Y$};%Y軸
    \draw[dashed](0,0) -- (3/2,3*1.732/2);
    \filldraw [red] (3/2,3*1.732/2) circle (0.5mm) node[right]{$\bm{r}$};%点r
    \draw [->](1.5,0) arc (0:30:1.5);%半径1.5の弧
    \draw [->](0.8,0) arc (0:60:0.8);%半径0.8の弧
    \coordinate (thrta_0) at (0.75,0) node at (thrta_0) [above right] {$\alpha$};%角度のラベル
    \coordinate (theta_0-alpha) at (1.5,0) node at (theta_0-alpha) [above right] {$\beta$};%角度のラベル
    %ここまで描画コマンド
  \end{tikzpicture}
  \caption{xy座標系とXY座標系の関係図。}
  \label{fig:rotate_xy_to_XY}
\end{figure}

これで,目標としていた図を描くことができました!最後にもう一度,出来上がった図を確認してみます。

f:id:LMCH:20191203010031p:plain

どうでしたか?意外と簡単に図を描くことが出来るんだな,ということを実感していただけたら嬉しいです。もっとも,途中の処理が雑なのでもう少しソースを美しくすることもできるはずですが,これだけ「ずぼら」でもいい感じの図が描けてしまったりします。面白そうだと思った方は,さらにいろいろな図を描いてみてください!

ギャラリー

今回はTikZ入門編の記事ということもあり,ここでは非常に簡単な題材を扱いました。もう少しTikZの面白さを雰囲気だけでも知ってもらいたいと感じたので,ギャラリーを用意してみました。

構造力学

f:id:LMCH:20191203105936p:plain

拙作ですが,実際に作った図の一つです。構造力学に限らず,TikZは力学一般についての図の作成がしやすいと感じることが多いです。美しいハッチングが手軽に出来るのも地味に嬉しかったりしますね。

また,TeXample.net [4]にはTikZのさまざまなサンプルが上がっています。その例をいくつか取り上げてみました。

ニューラルネットワーク

f:id:LMCH:20191203112435p:plain

今回紹介できなかったforeach分を回してノードを設定していくタイプの図。ノードの数が増えたり減ったりしても修正が簡単なのが嬉しいです。出典はこちら

インドの地図

f:id:LMCH:20191203113525p:plain

もう何でもありですね。行政区画の境目の座標を取ってくれば図が描けてしまいそうですが,この発想はなかった...。出典はこちら

おわりに

航空宇宙アドベントカレンダーということで何を題材にするかかなり迷いましたが,以前学科同期に「今度TikZ教えてくれ~」と言われたりしたこともあり,今回は航空宇宙関連の内容から離れてこのような内容に落ち着きました(きっと先輩方が航空宇宙にまつわる素晴らしい記事を書いてくださるはず!)。ブログを書くという行為自体も初めてなので,わかりやすい記事になっているかどうか心配ですがここまで読んでいただきありがとうございました。明日は,とても優秀な同期のkswmc360くんによる,オウム真理教所属軍用ヘリに関する記事みたいです。どうぞお楽しみに!

出典

[1]. CTAN: Package pgf, https://www.ctan.org/pkg/pgf (Accessed on 12/02/2019)

[2]. How do I pronounce "TikZ"? - TeX - LaTeX Stack Exchange, https://tex.stackexchange.com/questions/40938/how-do-i-pronounce-tikz (Accessed on 12/02/2019)

[3]. pgfmanual.pdf, http://ftp.jaist.ac.jp/pub/CTAN/graphics/pgf/base/doc/pgfmanual.pdf (Accessed on 12/03/2019)

[4]. TeXample.net: TikZ and PGF examples, http://www.texample.net/,(Accessed on 12/03/2019)}