この記事は TeX & LaTeX Advent Calendar 2019 の11日目の記事です。10日目は mod_poppo さんでした。 12日目は Mahito TANNO さんです。
今日は TikZ を使ってベン図を描いてみます。
【目次】
2 個のベン図
まずは基本中の基本,2 個の集合のベン図です。
完成図
ソース
工夫
- 色に透明度を使用することで,集合の交叉部分の色が自動的に重ね合わせられます。
\ratio
で 2 つの集合の噛み合い具合をコントロールできます。- 集合名のラベルの
\node
にfill=white
を指定して,背景に白い円を描くことでラベルを見やすくしています。
3 個のベン図
次は 3 個の集合のベン図です。極座標表示を使って,$\theta=90^\circ, 210^\circ, 330^\circ$ の方向に円の中心を配置するとよいでしょう。
完成図
ソース
応用例:集合の分配法則の図解
完成図
ソース
工夫
\usetikzlibrary{patterns}
してpattern=north west lines
と指定することで,斜線塗りを実現しています。\clip
で「切り抜き」を行うことで,中途半端な領域の塗りを実現しています。- なお,上記サンプルコードは pdfLaTeX で実行していますが,dvipdfmx を使う場合は注意が必要です。PGFの dvipdfmx 用ドライバは現時点では不具合があり,
patterns
ライブラリが dvipdfmx で上手く機能しません。これに対してはとりあえずこのパッチが有効です。このパッチを本家 PGF にプルリクエストを出したところマージされましたので,PGFの次期リリース版では修正されていることでしょう。
➡ 【更新】12/21付けでリリースされた PGF v.3.1.5 において修正されました。
4 個のベン図
4 個の円で $ {2^{4} =16} $ 個に分割されたベン図を描くことはできないので,楕円を使って実現します。
完成図
工夫
- 先に楕円を描き,それを
\begin{scope}[rotate=...]
で回転させています。
ソース
5 個のベン図
Wikipedia (en) によると,楕円 5 つを用いた対称的ベン図は,数学者 Branko Grünbaum によって1975年に考案されたそうです。
完成図
ソース
工夫
- 中心が原点から少しずれた楕円を,原点の周りに 72° ずつ回転させて対称的に生成しています。
一般の n 個のベン図をグレイコードを用いて自動生成する
これ以上集合の数が増えると,ますます複雑さが増して,なかなか手に負えなくなってきます。そこで,グレイコードを用いて,ベン図を機械的に生成しましょう。
グレイコードとは
グレイコード*1とは,隣接する符号間でビットが異なる桁が必ず 1 桁しか存在しない,という性質を持つ符号化法です。たとえば 4-bit グレイコードは次のように並びます。
0000 0001 0011 0010 0110 0111 0101 0100 1100 1101 1111 1110 1010 1011 1001 1000
グレイコードとベン図の関係
上記の 4-bit グレイコードを次のように桁ごとに分解して集合 A~D に割り当てます。また,縦方向を回転角 $\theta$ と見ます。それぞれの角度においてビットが変わった集合の境界線の半径を変えてやる,と考えます。
$ \theta $ | A | B | C | D |
---|---|---|---|---|
$ 0 $ | 0 | 0 | 0 | 0 |
$\pi / 8$ | 0 | 0 | 0 | 1 |
$\pi / 4$ | 0 | 0 | 1 | 1 |
$3\pi / 8$ | 0 | 0 | 1 | 0 |
$\pi / 2$ | 0 | 1 | 1 | 0 |
$5\pi / 8$ | 0 | 1 | 1 | 1 |
$3\pi / 4$ | 0 | 1 | 0 | 1 |
$7\pi / 8$ | 0 | 1 | 0 | 0 |
$\pi $ | 1 | 1 | 0 | 0 |
$9\pi / 8$ | 1 | 1 | 0 | 1 |
$5\pi / 4$ | 1 | 1 | 1 | 1 |
$11\pi / 8$ | 1 | 1 | 1 | 0 |
$3\pi / 2$ | 1 | 0 | 1 | 0 |
$13\pi / 8$ | 1 | 0 | 1 | 1 |
$7\pi / 4$ | 1 | 0 | 0 | 1 |
$15\pi / 8$ | 1 | 0 | 0 | 0 |
より詳細は,次の記事において大変詳しく説明されています。本記事でも,下記の記事のアルゴリズムを TeX 言語で実装し,TikZ で可視化することを目指しましょう。
グレイコードの生成
グレイコードを生成するには,再帰的に生成する方法と,ビット演算で一発で生成する方法とがあります。ビット演算が使える言語であれば,g = v ^ (v >> 1)
(右シフトしたものと自身とを XOR)によって,値 v
を対応するグレイコード g
に変換することができます。
TeX 言語でビット演算
TeX 言語の場合,ビット演算は標準では用意されていません。また,expl3 の関数群にもビット演算はないようです。ですが,TeX Live に収録されている Oberdiek 氏の作品の一つ bitset パッケージ を使えば,ビット演算が可能となります。
たとえば,10進法で表した 11
という値を 4-bit グレイコードに変換したいときは,次のようにして変換できます。
% 10進法での 11 を2進法表示した 1011 をビットセット gray としてセット \bitsetSetDec{gray}{11} % gray のコピーを gray2 として定義(⇒ gray = gray2 = 1011) \bitsetLet{gray2}{gray} % gray2 を右に1桁ビットシフト(⇒ gray2 = 0101) \bitsetShiftRight{gray2}{1} % gray と gray2 を XOR したものを gray として定義(⇒ gray = 1011 ^ 0101 = 1110) \bitsetXor{gray}{gray2} % gray を4桁の2進法表示した文字列を \graycode として定義 (\graycode -> 1110) \edef\graycode{\bitsetGetBin{gray}{4}}
TikZ + グレイコードによるベン図の自動生成結果
各集合の色は,色相環を n 等分することで決定しています。
3 個のベン図
4 個のベン図
5 個のベン図
6 個のベン図
7 個のベン図
8 個のベン図
9 個のベン図
10 個のベン図
もはやわけが分からなくなってきましたが,込み入っている部分を拡大するとこうなっています。
集合の境界線が激しく動いていますね……!
TikZ + グレイコードによるベン図の自動生成ソースコード
一般の n 個の集合からなるベン図を TikZ で自動生成する TeX コードです。\drawVenn{...}
の引数をいじることで任意の個数の集合からなるベン図を自動生成できます。
参考:回転対称性を持つ美しいベン図は?
今回はグレイコードを用いてベン図を自動生成しましたが,対称性はなくあまり綺麗なベン図ではありませんでした。ちなみに,回転対称性を持つベン図が描けるのは $n$ が素数の場合に限るのだそうです。$n=7, 11, 13$ の場合の美しい対称的ベン図の構造,および論文へのリンクが,次のページに掲載されています。
リンク先のページ・論文から,$n=7, 11, 13$ の場合の美しい対称的ベン図を引用しておきます。
7 個の対称的ベン図
11 個の対称的ベン図
13 個の対称的ベン図
*1:グレイコードの「グレイ」は,Frank Gray という人名に由来するので,灰色 (grey/gray) やロックバンド (GLAY) とは無関係です。