データの可視化をする上で、性別ごとのヒストグラムや、年代ごとの折れ線グラフなど、ある特定の層やグループごとに色分けをしてグラフをかくことがあります。今回は、簡単にグループごとの色分けグラフを書くための、2つの方法をご紹介します。
積み上げ棒グラフを一瞬で作成する方法も、ご紹介しています。
seaborn
でかく
1つ目は、seaborn
を使う方法です。seaborn
は、リッチなグラフを書けることで有名ですが、グループ別のグラフもhue
という引数で簡単にかくことができます。
初めに、可視化用の仮想健康診断データを作っておきます。
import random import seaborn as sns import matplotlib.pyplot as plt import pandas as pd import numpy as np # 仮想の健康診断データ random.seed(123) gender = np.random.choice(["Men", "Women"], size=100, replace=True) age = np.random.choice(np.arange(20, 60, 10), size=100, replace=True) height = np.where(gender == "Men", np.random.normal(170, 10, 100), np.random.normal(150, 10, 100)) weight = height - 100 + np.random.normal(0, 10, 100) medical_data = pd.DataFrame({"gender":gender, "age":age, "height":height, "weight":weight})
gender | age | height | weight |
---|---|---|---|
Men | 30 | 169.69 | 79.1459 |
Men | 40 | 192.411 | 80.2841 |
Men | 30 | 178.483 | 89.89 |
Women | 50 | 144.909 | 48.1535 |
Women | 40 | 153.979 | 46.9225 |
# 性別の身長ヒストグラム plt.figure(figsize=(4.2, 3)) sns.histplot(x="height", data=medical_data, hue="gender", binwidth=5, palette={"Men":"blue", "Women":"Orange"}) plt.show()
簡単ですね!
matplotlib
でかく
2つめは、集計用の関数であるgroupby
とmatplotlib
を組み合わせる方法です。
groupby
を適応したデータフレームをfor文に入れてかきます。
plt.figure(figsize=(4.2, 3)) for key, df in medical_data.groupby("gender"): # ここで色を指定する。 color = "blue" if key == "Men" else "Orange" plt.hist(df["height"], label=key, alpha=0.5, edgecolor="black") plt.legend(title="gender") plt.xlabel("height") plt.ylabel("Count")
少しトリッキーに見えますが、中身は単純です。groupby
を適応したデータフレームをfor文に入れると、groupingに用いたkeyとデータフレームがタプルになって返ってきます。それをmatplotlib
にわたせば、グルーブ別のグラフを書くことができます。
matplotlib
を使って細かく調整したい方はこちらですね!
ちなみにグループごとでグラフを分けたい場合、subplot
を使えば実現できます。
plt.figure(figsize=(4.2, 3)) for i, key_df in enumerate(medical_data.groupby(["gender"]), 1): plt.subplot(1, 2, i) key = key_df[0] df = key_df[1] plt.title(key) color = "blue" if key == "Men" else "Orange" plt.hist(df["height"], alpha=0.5, edgecolor="black", color=color) plt.xlabel("height") plt.ylabel("Count") plt.tight_layout()
2要因のグラフ
ついでに2つの要因でのグラフも書いてみましょう。ここでは、性別、年代別の身長体重の散布図を書いてみます。
seaborn
のhue
は、1つの要因でしか層別化できないため、先にデータを加工する必要があります。
# 性別、年代別の身長と体重散布図 # 性別に年代を結合して、新たなグループを作成する。 medical_data["gender_age"] = medical_data["gender"].str.cat(medical_data["age"].astype(str), sep="_") # カテゴリーの並び順を設定 group_order = sorted(medical_data["gender_age"].unique()) plt.figure(figsize=(8.4, 6)) sns.scatterplot(x="height", y="weight", data=medical_data, hue="gender_age", hue_order=group_order) plt.show()
matplotlibでは、labelを加工する必要がありますが、groupbyに変数を入れるだけでOKです。
plt.figure(figsize=(8.4, 6)) for key, df in medical_data.groupby(["gender", "age"]): # ここで色を指定する。 plt.scatter(df["height"], df["weight"], label="_" .join([key[0], str(key[1])])) plt.legend(title="gender_age") plt.xlabel("height") plt.ylabel("weight")
まとめ
seaborn
とmatplotlib
の使い分けとしては、
- 簡単にリッチなグラフを書きたい→
seaborn
- グラフの細かいところまで調整したい→
matplotlib
かなと思います。個人的には、いちいちseaborn
をimportするのが面倒なため、matplotlibをよく使ってます。
こればかりは好みの問題ですね、、
※本記事は筆者が個人的に学んだこと感じたことをまとめた記事になります。所属する組織の意見・見解とは無関係です。