マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

TikZ でノードを相対位置で配置する話

つまりコレに関する何か。

復習: ノードを普通に配置する話

通常、ノードの位置は at キーワードによって指示される。at が無い場合は“パス上の現在位置”となる。つまり、以下の 2 つの文は等価で、座標 (2,0) にノード A を配置する。(\node\path node の省略形であったことを思い出そう。)

\node[draw, circle] (A) at (2,0) {A};
\path (2,0) node[draw, circle] (A) {A};

ところで、ノードには普通「大きさ」があるので、ノードの「どこ」を (2,0) に合わせるのかも問題になる。上の例では、ノードの A の“中央(center)アンカー”が (2,0) に一致するように配置される。アンカーの指定は anchor パラメタで行える。他に、aboveright below left 等のパラメタでもアンカーの指定ができ、この場合はさらに「ずらす量」を指定することもできる。

\begin{tikzpicture}[every node/.style={draw, circle}]
  % 1cm間隔のグリッドを描く
  \draw[help lines, step=1cm] (-0.6,-0.6) grid (2.6,1.8);
  % Aの中央(center)アンカーを(0,0)に合わせる
  \node[anchor=center] (A) at (0,0) {A};
  % アンカーの既定値はcenterだから↓は↑と同じ
  \node                (A) at (0,0) {A};
  % Bの南(south)アンカーを(1,0)に合わせる
  \node[anchor=south]  (B) at (1,0) {B};
  % (1,0)の"すぐ上に"Bを配置する. ↑と同じ
  \node[above]         (B) at (1,0) {B};
  % (2,0)の"1cm上に"Cを配置する.
  \node[above=1cm]     (C) at (2,0) {C};
\end{tikzpicture}

これの出力結果は以下のようになる。*1

この above 等の指定は幾何学の図などで「点にラベルを付ける」のに用いられる。

\begin{tikzpicture}
  \fill (0,0) coordinate (O) circle[radius=2pt] node[left=2pt]  {O};
  \fill (2,1) coordinate (P) circle[radius=2pt] node[right=2pt] {P};
  \draw (O)--(P);
\end{tikzpicture}
相対配置してみる

TikZ の positioning ライブラリを読み込むと、above 等の配置用のパラメタが拡張されて、次のようにノードの“相対配置”ができるようになる。

\begin{tikzpicture}[every node/.style={draw}]
  \node[circle] (O) at (0,0) {O};
  % Oの"2cm左に"A
  \node[rectangle, left =2cm of O] (A) {A};
  % Oの"3cm右に"B
  \node[rectangle, right=3cm of O] (B) {B};
\end{tikzpicture}

ここでノード O と A の間には“実際に”2cm の隙間が空いている。つまり、A の東(east)アンカーと O の西(west)アンカーの距離が 2cm となる。すなわち、上のコードは次のように書いたものと等価である。

\begin{tikzpicture}[every node/.style={draw}]
  \node[circle] (O) at (0,0) {O};
  \node[rectangle, left =2cm] (A) at (O.west) {A};
  \node[rectangle, right=3cm] (B) at (O.east) {B};
\end{tikzpicture}

パラメタの値は「距離 of ノード」のように書く((「above=2cm of A.center」のようにノードの代わりにアンカーを指定することもできる。実際は、この A.center は「括弧無しの座標値」であり、従って「above={2cm of 2,1}」のような一見奇異な指定も可能である。))が、ここで距離の部分は省略することができ、この場合は node distance というパラメタの値(初期値は 1cm)が使われる。

\begin{tikzpicture}[every node/.style={draw, circle}]
  \node (O) at (0,0) {O};
  \node[left       =of O] {A};
  \node[above left =of O] {B};
  \node[above      =of O] {C};
  \node[above right=of O] {D};
  \node[right      =of O] {E};
\end{tikzpicture}
“above of=ノード”か“above=of ノード”か

以上のように、ノードの相対配置のためのパラメタ指定は、距離を省略すると、「above=of ノード」という形式である。ところが、昔の TikZ の解説や実践例を見ると、これと少し違った「above of=ノード」という指定がなされているのを見かける。実際に試してみると、これでも相対配置ができるように見える。

\begin{tikzpicture}[every node/.style={draw}]
  \node[circle] (O) at (0,0) {O};
  \node[rectangle, left of =O] (A) {A};
  \node[rectangle, right of=O] (B) {B};
\end{tikzpicture}

実は、この“above of というパラメタ”は古い TikZ で採用されていた指定方法で、現在では互換性*2のために残されているものの非推奨(deprecated)になっていて((tikz.code.tex の中の above of パラメタの定義の箇所を見ると“The following are deprecated”というコメントがある。))、それゆえ現在の PGF?TikZ のマニュアルには載っていない。

従って、現在の仕様に沿うには「above=of ノード」の方を用いるべきなのであるが、注意すべき点がある。古い「above of=ノード」と新しい「above=of ノード」は動作が少し異なるので、単純に “=” の位置だけ変えて書き直すわけにはいかないのである。

\begin{center}\begin{tikzpicture}
  [node distance=4cm,
   every node/.style={thick, minimum size=2cm,
     draw=black, fill=yellow!80}]
  \draw[help lines, step=1cm] (0,0) grid (10,10);
  \node    at (2,2) (A) {A};
  \node[above of=A] (B) {B}; % "above of=" 指定
  \node    at (8,2) (C) {C};
  \node[above=of C] (D) {D}; % "above=of" 指定
\end{tikzpicture}\end{center}

この結果を見れば判るように、新しい「above=of ノード」の方はノードの端のアンカー(C の north と D の south)の間の距離を node distance(上例では 4cm)に等しくするのに対し、古い「above of=ノード」のは中央(center)アンカー同士の距離を node distance にする。古い方の指定方法(先の例の B の配置)と等価な出力を現在の仕様に従う形で得るには例えば次のように書けばよい。

% "above=of〜"はanchorをsouthに変更する.
% 従ってその後でanchorを明示してcenterに戻す.
\node[above=of A.center, anchor=center] (B) {B};

*1:もちろんここでは「A」や「B」は 2 回重ねて描かれている。さらに悪いことに同じ名前のノードを 2 回定義している。普通はこんなことをしてはいけない。

*2:このパラメタを利用したパッケージが存在する。