箱図、バイオリン図、カーネル密度推定図など
Pythonによる簡単な描画例
以下の3グループのデータ
X1 = [31, 32, 22, 27, 20, 28, 25, 25, 28, 28, 26, 24, 28, 31, 29, 24, 29, 26, 20, 25]
X2 = [40, 35, 42, 44, 40, 35, 38, 39, 39, 35, 34, 36, 38, 38, 30, 35, 39, 39, 40, 37,31, 31, 42, 34, 38]
X3 = [22, 26, 25, 36, 26, 29, 28, 30, 31, 32, 28, 30, 29, 32, 30, 29, 32, 30, 33, 35, 35, 43, 38, 40, 41, 41, 45, 36, 37, 39]
について、データの分布を描いてみる。
まず、それぞれのヒストグラムは、次のスクリプトで描くことができる。
import matplotlib.pyplot as plt
X1 = [31, 32, 22, 27, 20, 28, 25, 25,
28, 28,
26, 24, 28, 31,
29, 24, 29, 26, 20, 25]
X2 = [40, 35, 42, 44, 40, 35, 38, 39,
39, 35,
34, 36, 38, 38,
30, 35, 39, 39, 40, 37,
31, 31, 42, 34,
38]
X3 = [22, 26, 25, 36, 26, 29, 28, 30,
31, 32,
28, 30, 29, 32,
30, 29, 32, 30, 33, 35,
35, 43, 38, 40,
41, 41, 45, 36, 37, 39]
plt.hist(X1)
plt.xlabel('X1', fontsize = 16)
plt.show()
plt.hist(X2)
plt.xlabel('X2', fontsize = 16)
plt.show()
plt.hist(X3)
plt.xlabel('X3', fontsize = 16)
plt.show()
上のスクリプトを実行すると、以下のようにそれぞれのヒストグラムが順番に表示される。
図1 右上のX印をクリックすると、このフォームは閉じられて次のフォーム(図2)が表示される。
図2 右上のX印をクリックすると、このフォームは閉じられて次のフォーム(図3)が表示される。
図3
3グループのデータのヒストグラムを1つのグラフにまとめて表示するスクリプトを以下のように用意した。
import matplotlib.pyplot as plt
X1 = [31, 32, 22, 27, 20, 28, 25, 25,
28, 28,
26, 24, 28, 31,
29, 24, 29, 26, 20, 25]
X2 = [40, 35, 42, 44, 40, 35, 38, 39,
39, 35,
34, 36, 38, 38,
30, 35, 39, 39, 40, 37,
31, 31, 42, 34,
38]
X3 = [22, 26, 25, 36, 26, 29, 28, 30,
31, 32,
28, 30, 29, 32,
30, 29, 32, 30, 33, 35,
35, 43, 38, 40,
41, 41, 45, 36, 37, 39]
plt.hist(X1, color = 'b', alpha = 0.5,
label = 'X1')
plt.hist(X2, color = 'g', alpha = 0.5,
label = 'X2')
plt.hist(X3, color = 'y', alpha = 0.5,
label = 'X3')
plt.legend()
plt.xlabel('X', fontsize = 16)
plt.ylabel('Frequency', fontsize = 14)
plt.show()
このスクリプトを実行すると、下図のグラフが表示される。
図4
パラメータalphaの値で透明度を調整しているので、異なるデータのヒストグラムが重ねられて描かれている。ヒストグラムの重なりのため、それぞれの分布が判りにくいので、ヒストグラムを曲線で置き換える。これをカーネル密度推定で行って描画するスクリプトを以下のように用意した。
import matplotlib.pyplot as plt
import seaborn as sns
X1 = [31, 32, 22, 27, 20, 28, 25, 25,
28, 28,
26, 24, 28, 31,
29, 24, 29, 26, 20, 25]
X2 = [40, 35, 42, 44, 40, 35, 38, 39,
39, 35,
34, 36, 38, 38,
30, 35, 39, 39, 40, 37,
31, 31, 42, 34,
38]
X3 = [22, 26, 25, 36, 26, 29, 28, 30,
31, 32,
28, 30, 29, 32,
30, 29, 32, 30, 33, 35,
35, 43, 38, 40,
41, 41, 45, 36, 37, 39]
plt.figure(figsize = (9, 7))
# in inches
plt.xticks(fontsize = 16)
plt.yticks(fontsize = 14)
sns.kdeplot(X1, color = 'b', linewidth
= 3, label = '$X_1$')
sns.kdeplot(X2, color = 'g', linewidth
= 3, label = '$X_2$')
sns.kdeplot(X3, color = 'y', linewidth
= 3, label = '$X_3$')
plt.xlabel('X', fontsize = 18)
plt.ylabel('Density', fontsize = 18)
plt.legend(fontsize = 16)
plt.show()
上のスクリプトを実行すると下図のグラフが描かれる。
図5
各データの分布を散布図のように描くこともできる。次のスクリプトを用意した。
import matplotlib.pyplot as plt
import seaborn as sns
X1 = [31, 32, 22, 27, 20, 28, 25, 25,
28, 28,
26, 24, 28, 31,
29, 24, 29, 26, 20, 25]
X2 = [40, 35, 42, 44, 40, 35, 38, 39,
39, 35,
34, 36, 38, 38,
30, 35, 39, 39, 40, 37,
31, 31, 42, 34,
38]
X3 = [22, 26, 25, 36, 26, 29, 28, 30,
31, 32,
28, 30, 29, 32,
30, 29, 32, 30, 33, 35,
35, 43, 38, 40,
41, 41, 45, 36, 37, 39]
X = X1 + X2 + X3
G = ['X1']*len(X1) + ['X2']*len(X2) +
['X3']*len(X3)
sns.stripplot(x = 'G', y = 'X', data =
{'X': X, 'G': G},
palette = ['r', 'g', 'b'])
plt.ylabel('Value', fontsize = 12)
plt.xlabel('Group', fontsize = 14)
plt.show()
上のスクリプトを実行すると下図のグラフが描かれる。
図6
図6の散布図は、四分位数の位置が示される箱図による表示を用いると分布の様子が解り易くなる。スクリプト例を以下に示す。
import matplotlib.pyplot as plt
import seaborn as sns
X1 = [31, 32, 22, 27, 20, 28, 25, 25,
28, 28,
26, 24, 28, 31,
29, 24, 29, 26, 20, 25]
X2 = [40, 35, 42, 44, 40, 35, 38, 39,
39, 35,
34, 36, 38, 38,
30, 35, 39, 39, 40, 37,
31, 31, 42, 34,
38]
X3 = [22, 26, 25, 36, 26, 29, 28, 30,
31, 32,
28, 30, 29, 32,
30, 29, 32, 30, 33, 35,
35, 43, 38, 40,
41, 41, 45, 36, 37, 39]
X = X1 + X2 + X3
G = ['X1']*len(X1) + ['X2']*len(X2) +
['X3']*len(X3)
sns.boxplot(x = 'G', y = 'X', data =
{'X': X, 'G': G},
palette = ['r', 'g', 'b'])
plt.ylabel('Value', fontsize = 12)
plt.xlabel('Group', fontsize = 14)
plt.show()
上のスクリプトを実行すると下図のグラフが描かれる。
図7
箱を横にするときは、次のようなスクリプトになる。
import matplotlib.pyplot as plt
import seaborn as sns
X1 = [31, 32, 22, 27, 20, 28, 25, 25,
28, 28,
26, 24, 28, 31,
29, 24, 29, 26, 20, 25]
X2 = [40, 35, 42, 44, 40, 35, 38, 39,
39, 35,
34, 36, 38, 38,
30, 35, 39, 39, 40, 37,
31, 31, 42, 34,
38]
X3 = [22, 26, 25, 36, 26, 29, 28, 30,
31, 32,
28, 30, 29, 32,
30, 29, 32, 30, 33, 35,
35, 43, 38, 40,
41, 41, 45, 36, 37, 39]
X = X1 + X2 + X3
G = ['X1']*len(X1) + ['X2']*len(X2) +
['X3']*len(X3)
sns.boxplot(y = 'G', x = 'X', data =
{'X': X, 'G': G}, orient = "h",
palette = ['r', 'g', 'b'])
plt.ylabel('Group', fontsize = 12)
plt.xlabel('Value', fontsize = 14)
plt.show()
上のスクリプトを実行すると下図のグラフが描かれる。
図8
データの分布の様子をカーネル密度推定による曲線で表すとバイオリン図が得られる。スクリプト例は以下のようである。
import matplotlib.pyplot as plt
import seaborn as sns
X1 = [31, 32, 22, 27, 20, 28, 25, 25,
28, 28,
26, 24, 28, 31,
29, 24, 29, 26, 20, 25]
X2 = [40, 35, 42, 44, 40, 35, 38, 39,
39, 35,
34, 36, 38, 38,
30, 35, 39, 39, 40, 37,
31, 31,
42, 34, 38]
X3 = [22, 26, 25, 36, 26, 29, 28, 30,
31, 32,
28, 30, 29, 32,
30, 29, 32, 30, 33, 35,
35, 43, 38, 40,
41, 41, 45, 36, 37, 39]
X = X1 + X2 + X3
G = ['X1']*len(X1) + ['X2']*len(X2) +
['X3']*len(X3)
sns.violinplot(x = 'G', y = 'X', data
= {'X': X, 'G': G},
palette = ['r', 'g', 'b'])
plt.ylabel('Value', fontsize = 12)
plt.xlabel('Group', fontsize = 14)
plt.show()
上のスクリプトを実行すると下図のグラフが描かれる。
図9
上の3つのグラフ、散布図、箱図、バイオリン図、を1つの画面にまとめて表示することもできる。以下に、スクリプト例を示す。
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
X1 = [31, 32, 22, 27, 20, 28, 25, 25,
28, 28,
26, 24, 28, 31,
29, 24, 29, 26, 20, 25]
X2 = [40, 35, 42, 44, 40, 35, 38, 39,
39, 35,
34, 36, 38, 38,
30, 35, 39, 39, 40, 37,
31, 31, 42, 34,
38]
X3 = [22, 26, 25, 36, 26, 29, 28, 30,
31, 32,
28, 30, 29, 32,
30, 29, 32, 30, 33, 35,
35, 43, 38, 40, 41,
41, 45, 36, 37, 39]
X = X1 + X2 + X3
G = ['X1']*len(X1) + ['X2']*len(X2) +
['X3']*len(X3)
dframe = pd.DataFrame({'X': X, 'G':
G})
sns.stripplot(x = 'G', y = 'X', data =
dframe,
palette = ['w', 'w', 'w'], jitter = 0.1,
size = 10, linewidth = 2)
sns.boxplot(x = 'G', y = 'X', data =
dframe,
palette = ['r', 'g', 'b'])
sns.violinplot(x = 'G', y = 'X', data
= dframe,
palette = ['r', 'g', 'b'])
plt.ylabel('Value', fontsize = 12)
plt.xlabel('Group', fontsize = 14)
plt.show()
上のスクリプトを実行すると下図のグラフを得る。
図10
なお、Pythonによるグラフ描画の説明を
岡本安晴(著)「いまさら聞けないPythonでデータ分析―多変量解析,ベイズ統計分析(PyStan,PyMC)―」丸善出版
で行っている。