pythonのグラフ描画ライブラリである「matplotlib」で、箱ひげ図を作成する方法について紹介します。
本記事では、下記の内容を紹介しています。
この記事で分かること
- 箱ひげ図とは
- 箱ひげ図を作成する方法
- 外れ値を表示しないようにする方法
- 複数の箱ひげ図を並べて表示する方法
- 横軸にラベルを表示する方法
- 【参考】箱ひげ図をpandas(dataframe)から作成する方法
はじめに、基本的な内容として、箱ひげ図を作成する方法を紹介します。
そのあとに、箱ひげ図を複数並べて表示する方法、箱ひげ図の横軸にラベルを表示する方法など、箱ひげ図を見やすく表示する方法について紹介します。
スポンサーリンク
箱ひげ図とは
はじめに、箱ひげ図について簡単に説明します。
箱ひげ図は、データの分布やばらつきを確認したいときに役立つグラフです。
箱ひげ図の情報には、データの最大値、最小値情報に加え、"四分位数"と呼ばれる、データの分布情報が含まれています。
"四分位数"とは、データを小さい順に並べ、データ個数で4分割した際の、区切り値のことを指します。
データを個数で4分割すると、25%刻みで3つの区切り値が決まります。小さい方からそれぞれ
- 25パーセンタイル:第1四分位
- 50パーセンタイル:第2四分位(中央値)
- 75パーセンタイル:第3四分位
となります。
四分位数ごとに25%ずつデータが入っているので、第1四分位~第3四分位の間には50%のデータが入っていることになります。
上記の箱ひげ図を見ると、中央値である第2四分位と第1四分位、第2四分位と第3四分位の間隔が等間隔なので、「データが大小に均等に分布していそうだ」ということも読み取ることができます。
「はこ」から、上下に出ている線は「ひげ」と呼ばれます。
上のひげは、第3四分位から、四分位範囲の1.5倍まで伸びます。これ以上大きい値がある場合は、外れ値として表示されます。
下のヒゲは、第1四分位から、四分位範囲の1.5倍まで伸びます。これ以上小さい値がある場合は、外れ値として表示されます。
以上、ここまでが箱ひげ図の簡単な説明になります。
少しくどいかもしれませんが、補足として、次の項で、箱ひげ図とヒストグラムを並べて比較してみます。
【補足】ヒストグラムと箱ひげ図を並べて表示
ヒストグラムと箱ひげ図を並べて表示することで、箱ひげ図の見かたについて補足します。
以下のサンプルコードは、学校の数学のテストの点数分布をテーマに作成してみました。
平均点80、標準偏差10の正規分布のサンプルを、1000個作成しています。
点数は100点を超えることも、0点未満になることもないので、関数 func_score を作成して調整しています。
以下、ヒストグラムと箱ひげ図を並べて表示するサンプルコードです。
### ヒストグラムと箱ひげ図を並べて表示
import matplotlib.pyplot as plt
import numpy as np
def func_score(list_score) :
list_score = [100 if score >= 100 else score for score in list_score]
list_score = [0 if score <= 0 else score for score in list_score]
return list_score
math = np.random.normal(loc=80, scale=10, size=1000)
math = func_score(math)
x = np.array(math)
x_sort = np.sort(x)
print(f'平均 : {np.average(x)}')
print(f'標準偏差 : {np.std(x)}')
print(f'25% : {x_sort[249]}')
print(f'50% : {x_sort[499]}')
print(f'75% : {x_sort[749]}')
"""
平均 : 79.9753740796817
標準偏差 : 9.783026965703362
25% : 73.35755898881372
50% : 80.3854327587073
75% : 86.9875693430813
"""
fig = plt.figure()
ax1 = fig.add_subplot(1, 2, 1)
ax2 = fig.add_subplot(1, 2, 2)
ax1.hist(math, bins=20, range=(0, 100))
ax2.boxplot(x)
ax2.set_xticklabels(['math'])
plt.show()
コード実行後、表示されるグラフはこちらになります。
箱ひげ図の第1四分位~第3四分位の「ハコ」が、だいたい73点から87点くらいの間にあり、この範囲にデータの50%が集まっていることが分かります。ヒストグラムを見てみると、たしかにこの範囲にデータの半分程度が集まっていそうに見えます。
また、中央値である第2四分位と第1四分位、第2四分位と第3四分位の間隔が等間隔なので、「ハコ」の中では、データが大小に均等に分布していそうです。ヒストグラムを見ると、たしかに「ハコ」の範囲では、データが大小均等に分布していそうに見えます。
最大値は100点までになっているため、「ヒゲ」は四分位範囲の1.5倍まで伸びきっていません。
最小値は、47点です。四分位範囲の1.5倍より外側にあるので、外れ値として表示されています。
> def func_score(list_score) :
> list_score = [100 if score >= 100 else score for score in list_score]
> list_score = [0 if score <= 0 else score for score in list_score]
> return list_score
テストの点数が、100点以下0点以上に収まるように修正する関数です。
リスト内包表記で作成してみましたが、見にくくなってしまいました。普通にif、elif、elseで作成した方が見やすくなると思います。
内包表記については、下記の記事で紹介しています。
> math = np.random.normal(loc=80, scale=10, size=1000)
平均点80、標準偏差10の正規分布のサンプルを、1000個作成しています。
スポンサーリンク
matplotlibで箱ひげ図を作成する方法
matplotlibには、箱ひげ図を作成するメソッドとして、 matplotlib.pyplot.boxplot が用意されています。
matplotlib.pyplot.boxplot の引数の指定方法について、 公式ドキュメント から引用しました。
matplotlib 公式ドキュメント
matplotlib.pyplot.boxplot の詳しい使用方法については、 公式ドキュメント にて御確認ください。
以下、 matplotlib.pyplot.boxplot を用いて箱ひげ図を作成するサンプルコードです。
### matplotlibで箱ひげ図を作成
import matplotlib.pyplot as plt
import numpy as np
def func_score(list_score) :
list_score = [100 if score >= 100 else score for score in list_score]
list_score = [0 if score <= 0 else score for score in list_score]
return list_score
math = np.random.normal(loc=80, scale=10, size=100)
math = func_score(math)
plt.boxplot(math)
plt.show()
コード実行後、表示されるグラフはこちらになります。
> plt.boxplot(math)
matplotlib.pyplot.boxplot に、箱ひげ図生成用のデータ "math" を引数として渡しています。
matplotlibの箱ひげ図に外れ値が表示されないようにする
つぎに、箱ひげ図に外れ値を表示しないようにする方法を紹介します。
まず、通常の方法でmatplotlibで箱ひげ図を作成すると、外れ値が表示されます。
以下、箱ひげ図で外れ値が表示されるサンプルコードです。
### 外れ値が表示される例
import matplotlib.pyplot as plt
import numpy as np
def func_score(list_score) :
list_score = [100 if score >= 100 else score for score in list_score]
list_score = [0 if score <= 0 else score for score in list_score]
return list_score
math = np.random.normal(loc=70, scale=10, size=1000)
math = func_score(math)
plt.boxplot(math)
plt.show()
コード実行後、表示されるグラフはこちらになります。
つぎに、箱ひげ図に外れ値を表示しない方法を紹介します。
matplotlib.pyplot.boxplot の引数として、sym=''を指定すると、外れ値が表示されなくなります。
以下、箱ひげ図で外れ値を表示しないサンプルコードです
### 外れ値を表示しない例
import matplotlib.pyplot as plt
import numpy as np
def func_score(list_score) :
list_score = [100 if score >= 100 else score for score in list_score]
list_score = [0 if score <= 0 else score for score in list_score]
return list_score
math = np.random.normal(loc=70, scale=10, size=1000)
math = func_score(math)
plt.boxplot(math, sym='')
plt.show()
コード実行後、表示されるグラフはこちらになります。
> plt.boxplot(math, sym='')
外れ値のシンボルとして、空白を指定しているため、外れ値が表示されなくなります。
このシンボルに他の記号を指定すると、外れ値の記号を変更することができます。
参考までに外れ値の記号を星型にする例を紹介します。
【参考】外れ値の記号を変える
外れ値の記号を星型にする例を紹介します。
以下、サンプルコードです。
### 外れ値の記号を変える
import matplotlib.pyplot as plt
import numpy as np
def func_score(list_score) :
list_score = [100 if score >= 100 else score for score in list_score]
list_score = [0 if score <= 0 else score for score in list_score]
return list_score
math = np.random.normal(loc=70, scale=10, size=1000)
math = func_score(math)
plt.boxplot(math, sym='*')
plt.show()
コード実行後、表示されるグラフはこちらになります。
plt.boxplot(math, sym='*')
外れ値のシンボルとして、 sym='*' を指定しています。
スポンサーリンク
matplotlibで複数の箱ひげ図を並べて表示
複数の箱ひげ図を並べて表示する方法を紹介します。
matplotlib.pyplot.boxplot の引数として、箱ひげ図作成用のデータをリスト型で指定することで、箱ひげ図を並べて表示することができます。
以下、サンプルコードです。
### 複数の箱ひげ図を並べて表示
import matplotlib.pyplot as plt
import numpy as np
def func_score(list_score) :
list_score = [100 if score >= 100 else score for score in list_score]
list_score = [0 if score <= 0 else score for score in list_score]
return list_score
math = np.random.normal(loc=80, scale=10, size=100)
math = func_score(math)
english = np.random.normal(loc=60, scale=20, size=100)
english = func_score(english)
plt.boxplot([math,english])
plt.show()
コード実行後、表示されるグラフはこちらになります。
> plt.boxplot([math,english])
2つのデータを、リスト型で引数として渡しています。
matplotlibで箱ひげ図に横軸にラベルを表示
次に、箱ひげ図の横軸にデータラベルを表示する方法について紹介します。
matplotlib.pyplot.boxplot の引数として、labelsを指定することで、横軸にラベルを表示することができます。
以下、サンプルコードです。
### 横軸にデータラベルを表示
import matplotlib.pyplot as plt
import numpy as np
def func_score(list_score) :
list_score = [100 if score >= 100 else score for score in list_score]
list_score = [0 if score <= 0 else score for score in list_score]
return list_score
math = np.random.normal(loc=80, scale=10, size=100)
math = func_score(math)
english = np.random.normal(loc=60, scale=20, size=100)
english = func_score(english)
plt.boxplot([math,english], labels=['math', 'english'])
plt.show()
コード実行後、表示されるグラフはこちらになります。
> plt.boxplot([math,english], labels=['math', 'english'])
ラベル名を、リスト型で、引数 labels に渡しています。
スポンサーリンク
【参考】箱ひげ図をpandas(dataframe)から作成
次に、matplotlibではなく、pythonのデータ解析ライブラリである「pandas」を用いて箱ひげ図を作成する方法について紹介します。
pandasのメソッドとしてplotが用意されており、簡単にさまざまなグラフを作成することができます。
以下、pandasを用いて箱ひげ図を作成するサンプルコードです。
### 箱ひげ図をpandasを用いて作成
import numpy as np
import pandas as pd
def func_score(list_score) :
list_score = [100 if score >= 100 else score for score in list_score]
list_score = [0 if score <= 0 else score for score in list_score]
return list_score
data_m = np.random.normal(loc=80, scale=10, size=100)
data_m = func_score(data_m)
data_e = np.random.normal(loc=50, scale=20, size=100)
data_e = func_score(data_e)
data_s = np.random.normal(loc=70, scale=5, size=100)
data_s = func_score(data_s)
col = ['math', 'english', 'science']
df = pd.DataFrame(data=list(zip(data_m,data_e,data_s)), columns=col)
df.plot.box()
データフレーム df には、下記のデータが格納されています。
コード実行後、表示されるグラフはこちらになります。
> df = pd.DataFrame(data=list(zip(data_m,data_e,data_s)), columns=col)
3つのリストからデータフレームを作成しています。
zip関数を用いて3つのリストをまとめ、list関数でリストに変換して、データフレームのデータとしています。
zip関数については、下記の記事で紹介しています。
> df.plot.box()
plotメソッドのbox( )を用いて、データフレームから箱ひげ図を作成しています。
【参考】pandasで統計情報を算出する方法
参考として、pandasの便利なメソッドを紹介します。
pandasのdescribe( )というメソッドを使用すると、データフレームの統計情報を簡単に出力できます。
箱ひげ図と併せて使うと強力なメソッドです。
### pandasで統計情報を算出する方法
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
def func_score(list_score) :
list_score = [100 if score >= 100 else score for score in list_score]
list_score = [0 if score <= 0 else score for score in list_score]
return list_score
data_m = np.random.normal(loc=80, scale=10, size=100)
data_m = func_score(data_m)
data_e = np.random.normal(loc=50, scale=20, size=100)
data_e = func_score(data_e)
data_s = np.random.normal(loc=70, scale=5, size=100)
data_s = func_score(data_s)
col = ['math', 'english', 'science']
df = pd.DataFrame(data=list(zip(data_m,data_e,data_s)), columns=col)
df.describe()
コードを実行すると、下記の統計情報が出力されます。
箱ひげ図で描画される「四分位数」や、「平均」、「標準偏差」といった情報が簡単に出力できます。
スポンサーリンク