Pynote

Python、機械学習、画像処理について

matplotlib - ベン図を Python の matplotlib-venn で作成する。

matplotlib-venn

matplotlib の図形描画機能を利用したベン図を作成するライブラリである。
pip でインストールできる。

pip install matplotlib-venn

各パラメータの指定方法

内部的には matplotlib の関数を呼び出してるだけなので、色 set_colors や線のスタイル linestyle、線の太さlinewidth の指定方法は matplotlib と同じである。

2つの集合のベン図

ラベル付きのベン図を作成する venn2 とラベルなしのベン図を作成する venn2_circles がある。

venn2(subsets, set_labels=('A', 'B'), set_colors=('r', 'g'), alpha=0.4,
      normalize_to=1.0, ax=None, subset_label_formatter=None)

venn2_circles(subsets, normalize_to=1.0, alpha=1.0, color='black',
              linestyle='solid', linewidth=2.0, ax=None, **kwargs)

必要な import

import matplotlib.pyplot as plt
from matplotlib_venn import venn2, venn2_circles

集合の指定方法

A, B という2つの集合がある場合、各部分集合を次のように表現する。

\displaystyle
\begin{array}{|c|c|}
\hline
A \setminus B & 10  \\
\hline
B \setminus A & 01  \\
\hline
A \cap B & 11  \\
\hline
\end{array}

subsets には各部分集合 10, 01, 11 の大きさを指定する。
また、大きさの代わりに2つの set を指定でき、この場合、大きさは自動的に計算される。

# 10, 01, 11 の各集合の大きさをタプルまたはリストで指定する。
venn2(subsets=(2, 2, 1))
plt.show()

# 10, 01, 11 の各集合の大きさを dict で指定する。
venn2(subsets={'10': 2, '01': 2, '11': 1})
plt.show()

# 2つの集合を指定する。
# 指定した集合から 01, 10, 11 の各集合の大きさが自動的に計算される。
a = set(['A', 'B', 'C', 'D'])
b = set(['D', 'E', 'F'])
venn2(subsets=[a, b])
plt.show()


ラベルを設定する。

set_labels でラベルを設定できる。

# set_labels で2つの集合のラベル名を指定する。
venn2(subsets=(2, 2, 1), set_labels=('Red', 'Green'))
plt.show()


色を設定する。

set_colors で色を設定できる。

# set_colors で2つの集合の色を指定する。
venn2(subsets=(2, 2, 1), set_colors=('skyblue', 'lightgreen'))
plt.show()


透過度を設定する。

alpha で透過度を設定できる。

# alpha で2つの集合の透過度を指定する。
venn2(subsets=(2, 2, 1), alpha=0.2)
plt.show()


ラベルなしのベン図を作成する。

venn2_circles でラベルなしのベン図を作成できる。
linestyle で線のスタイル、linewidth で線の幅を設定できる。

# alpha で2つの集合の透過度を指定する。
venn2_circles(subsets=(2, 2, 1), linestyle='--', linewidth=2)
plt.show()


より細かい調整をするには

各部分集合は、図形部分は matplotlib.patches.PathPatch オブジェクト、ラベルは matplotlib.text.Text オブジェクトでそれぞれ構成されているので、matplotlib のプロパティを設定することでより細かい設定を行える。
作成したベン図オブジェクトの get_patch_by_id(id) で matplotlib.patches.PathPatch、get_label_by_id(id) で matplotlib.text.Text を取得できる。

venn = venn2(subsets=(2, 2, 1), alpha=0.2)
set10 = venn.get_patch_by_id('10')
set01 = venn.get_patch_by_id('01')
set11 = venn.get_patch_by_id('11')
print(type(set01))  # matplotlib.patches.PathPatch

# 図形の色を変更する。
set10.set_color('w')
set01.set_color('w')
set11.set_color('skyblue')

# 枠線の色を変更する。
set10.set_edgecolor('black')
set01.set_edgecolor('black')
set11.set_edgecolor('black')
plt.show()


venn = venn2(subsets=(2, 2, 1), alpha=0.2)
label10 = venn.get_label_by_id('10')
label01 = venn.get_label_by_id('01')
label11 = venn.get_label_by_id('11')
print(type(label01))  # <class 'matplotlib.text.Text'>

# テキストを変更する。
label10.set_text('10')
label01.set_text('01')
label11.set_text('11')
plt.show()


3つの集合のベン図

ラベル付きのベン図を作成する venn3 とラベルなしのベン図を作成する venn3_circles がある。

venn3(subsets, set_labels=('A', 'B', 'C'), set_colors=('r', 'g', 'b'),
      alpha=0.4, normalize_to=1.0, ax=None, subset_label_formatter=None)

venn3_circles(subsets, normalize_to=1.0, alpha=1.0, color='black',
              linestyle='solid', linewidth=2.0, ax=None, **kwargs)

必要な import

import matplotlib.pyplot as plt
from matplotlib_venn import venn3, venn3_circles

集合の指定方法

A, B, C という2つの集合がある場合、各部分集合を次のように表現する。

\displaystyle
\begin{array}{|c|c|}
\hline
A \setminus (B \cup C) & 100 \\
\hline
B \setminus (A \cup C) & 010 \\
\hline
C \setminus (A \cup B) & 001 \\
\hline
(A \cup B) \setminus C & 110 \\
\hline
(A \cup C) \setminus B & 101 \\
\hline
(B \cup C) \setminus A & 011 \\
\hline
A \cap B \cap C & 111 \\
\hline
\end{array}

subsets には各部分集合 100, 010, 001, 110, 101, 011, 111 の大きさを指定する。
また、大きさの代わりに3つの set を指定でき、この場合、大きさは自動的に計算される。

# 100, 010, 001, 110, 101, 011, 111 の各集合の大きさをタプルまたはリストで指定する。
venn3(subsets=(2, 2, 2, 1, 1, 1, 1))
plt.show()

# 100, 010, 001, 110, 101, 011, 111 の各集合の大きさを dict で指定する。
venn3(subsets={'100': 2, '010': 2, '001': 2,
               '110': 1, '101': 1, '011': 1, '111': 1})
plt.show()

# 指定した集合から 100, 010, 001, 110, 101, 011, 111 の
# 各集合の大きさが自動的に計算される。
a = set(['A', 'B', 'C', 'D'])
b = set(['D', 'E', 'F'])
c = set(['B', 'D', 'G'])
venn3(subsets=(a, b, c))
plt.show()

他のパラメータの指定方法は venn2, venn2_circles と同じである。

venn3_circles(subsets=(2, 2, 2, 1, 1, 1, 1), linestyle='-', linewidth=2)
plt.show()