はじめに
データの基礎分析で質的変数の度数分布図(ヒストグラム)を作る必要がある場面になったとき、matplotlib
の hist
では少し物足りなくなった事情があったので、備忘録として記事に残しておく。
データセットの準備
データセットは質的変数が含まれていればなんでもいいので、iris の場合の例を示す。
#モジュールのインポート
from sklearn import datasets
import pandas as pd
import matplotlib.pyplot as plt
#(量的変数は使わないけど)データセットの読み込み
iris = datasets.load_iris()
df = pd.DataFrame(iris.data)
#質的変数のラベルを追加する。
df['species'] = iris.target
df.loc[df['species'] == 0, 'species'] = "setosa"
df.loc[df['species'] == 1, 'species'] = "versicolor"
df.loc[df['species'] == 2, 'species'] = "virginica"
print(df)
出力
0 1 2 3 species
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa
.. ... ... ... ... ...
145 6.7 3.0 5.2 2.3 virginica
146 6.3 2.5 5.0 1.9 virginica
147 6.5 3.0 5.2 2.0 virginica
148 6.2 3.4 5.4 2.3 virginica
149 5.9 3.0 5.1 1.8 virginica
hist
を使ったプロット
質的変数(ラベルデータ等…)でもhist
でヒストグラムが作成できる。
fig1 = plt.figure()
plt.hist(df["species"])
plt.show()
fig1.savefig("iris_speacies_hist.png")
しかし、完成したプロットを見て頂ければ分かる通り、setosa, versicolor は種類名がグラフの左側にあるのに対して、virginica はグラフの右側にある。種類の数が少なければ大きな問題には見えないが、種類が増えるとプロットが重なる原因になってしまう。何より不均一なのが気持ち悪い。
度数分布表を作成し、bar
を使ったプロット
上記の問題を解消するため、度数分布表を別途作成し、bar
によってヒストグラムを描く方法を取る。
#度数分布を辞書型で作成
col = set(df["species"])
data = df["species"].tolist()
dosu = { key: data.count(key) for key in col}
ind = range(len(dosu.keys()))
#プロット部分
fig2 = plt.figure()
plt.xticks(ind, dosu.keys())
plt.bar(ind, dosu.values())
plt.show()
fig2.savefig("iris_speacies_bar.png")
これによりきちんと種類名の真ん中にラベルが来て、見やすいヒストグラムとなった。
おわりに
質的変数を可視化する際にはちょっとした処理が必要だったので、そのメモを残すために記事を書いた。もし、hist
を使ってきれいに図がかける方法をご存じの方が居れば、是非コメントお願いします!