ボックスプロット

簡単なボックスプロット

ボックスプロットは、matplotlib ライブラリーの boxplot メソッドを利用して作成する。もっとも簡単な方法として、ボックスプロットにしたいデータをリストに保存し、そのリストを boxplot メソッドに渡す。複数項目ある場合は、リストのリストとして与える。x 軸のラベルは labels オプションで指定する。

import numpy as  np
from matplotlib import pyplot as plt
import seaborn as sns

sns.set()
sns.set_style('whitegrid')
sns.set_palette('gray')

np.random.seed(2018)

x1 = np.random.normal(10, 2, 20)
x2 = np.random.normal(15, 3, 20)
x3 = np.random.normal(5, 1, 20)

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.boxplot([x1, x2, x3], labels=['leaf', 'stem', 'root'])
ax.set_xlabel('tissue')
ax.set_ylabel('dry weight [g]')
ax.set_ylim(0, 20)

plt.show()
matplotlib/seaborn boxplot を利用して作成したボックスプロット

ボックスプロットから、データの四分位点などをすぐに確認できる。しかし、データの実際の値を確認できないといった欠点がある。そのため、現在では、ボックスプロットの上に、jitter プロットを重ねるよなグラフも見られるようになった。jitter プロットは、matplotlib 標準のメソッドを使って描くのは難しいので、ここでは seaborn ライブラリー中の stripplot メソッドを使う。

import numpy as  np
import pandas as pd
from matplotlib import pyplot as plt
import seaborn as sns

sns.set()
sns.set_style('whitegrid')
sns.set_palette('Set3')

np.random.seed(2018)

df = pd.DataFrame({
    'leaf': np.random.normal(10, 2, 20),
    'stem': np.random.normal(15, 3, 20),
    'root': np.random.normal(5, 1, 20)
})

df_melt = pd.melt(df)
print(df_melt.head())
##   variable      value
## 0     leaf   9.446465
## 1     leaf  11.163702
## 2     leaf  14.296799
## 3     leaf   7.441026
## 4     leaf  11.004554

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
sns.boxplot(x='variable', y='value', data=df_melt, showfliers=False, ax=ax)
sns.stripplot(x='variable', y='value', data=df_melt, jitter=True, color='black', ax=ax)

plt.show()
matplotlib/seaborn pyplot.boxplot を利用して作成したボックスプロットと jitter plot を重ね合わせたグラフ。

横に並べたボックスプロット

複数項目の場合は、次のように、データを一つのデータフレームにまとめてから、seaborn ライブラリーの boxplot メソッドを使うと簡単に描ける。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

plt.style.use('default')
sns.set()
sns.set_style('whitegrid')
sns.set_palette('Set3')

np.random.seed(2018)

# data of Ta (T. aestivum) group
dfTa = pd.DataFrame({
    'leaf': np.random.normal(10, 2, 20),
    'stem': np.random.normal(15, 3, 20),
    'root': np.random.normal(5, 1, 20)
})

# data of At (A. tauschii) group
dfAt = pd.DataFrame({
    'leaf': np.random.normal(12, 3, 20),
    'stem': np.random.normal(12, 3, 20),
    'root': np.random.normal(6, 2, 20)
})

# merge the two data frames to one data frame
dfTa_melt = pd.melt(dfTa)
dfTa_melt['species'] = 'T. aestivum'
dfAt_melt = pd.melt(dfAt)
dfAt_melt['species'] = 'A. tauschii'

df = pd.concat([dfAt_melt, dfTa_melt], axis=0)
print(df.head())
##   variable      value      species
## 0     leaf  11.871913  A. tauschii
## 1     leaf  16.013749  A. tauschii
## 2     leaf  11.930841  A. tauschii
## 3     leaf  14.794698  A. tauschii
## 4     leaf   8.642995  A. tauschii

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
sns.boxplot(x='variable', y='value', data=df, hue='species', palette='Dark2', ax=ax)

ax.set_xlabel('tissue')
ax.set_ylabel('dry weight [g]')
ax.set_ylim(0, 20)
ax.legend()

plt.show()
matplotlib/seaborn pyplot.boxplot を利用して作成した複数属性のボックスプロット。

ボックスプロットが複数個横に並んでも、jitter プロットを追加できる。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

plt.style.use('default')
sns.set()
sns.set_style('whitegrid')
sns.set_palette('Set3')

np.random.seed(2018)

# data of Ta (T. aestivum) group
dfTa = pd.DataFrame({
    'leaf': np.random.normal(10, 2, 20),
    'stem': np.random.normal(15, 3, 20),
    'root': np.random.normal(5, 1, 20)
})

# data of At (A. tauschii) group
dfAt = pd.DataFrame({
    'leaf': np.random.normal(12, 3, 20),
    'stem': np.random.normal(12, 3, 20),
    'root': np.random.normal(6, 2, 20)
})


dfTa_melt = pd.melt(dfTa)
dfTa_melt['species'] = 'T. aestivum'
dfAt_melt = pd.melt(dfAt)
dfAt_melt['species'] = 'A. tauschii'

df = pd.concat([dfAt_melt, dfTa_melt], axis=0)
print(df.head())
##   variable      value      species
## 0     leaf  11.871913  A. tauschii
## 1     leaf  16.013749  A. tauschii
## 2     leaf  11.930841  A. tauschii
## 3     leaf  14.794698  A. tauschii
## 4     leaf   8.642995  A. tauschii

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

sns.boxplot(x='variable', y='value', data=df, hue='species', showfliers=False, palette='Set3', ax=ax)
sns.stripplot(x='variable', y='value', data=df, hue='species', dodge=True, jitter=True, color='black', ax=ax)


handles, labels = ax.get_legend_handles_labels()

# 4 legends for defaul: boxplot x 2 species, and stripplot x 2 species
# use the first 2 legends
ax.legend(handles[0:2], labels[0:2])
ax.set_xlabel('tissue')
ax.set_ylabel('dry weight [g]')
ax.set_ylim(0, 20)
plt.show()
matplotlib/seaborn pyplot.boxplot を利用して作成した複数属性のボックスプロット。jitter plot あり。