matplotlib ライブラリ

【python】matplotlibで箱ひげ図を作成する方法

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 公式ドキュメント

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関数については、下記の記事で紹介しています。

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()

コードを実行すると、下記の統計情報が出力されます。

実行結果

箱ひげ図で描画される「四分位数」や、「平均」、「標準偏差」といった情報が簡単に出力できます。

スポンサーリンク

-matplotlib, ライブラリ
-,