seaborn

【Python】【Seaborn】複数の棒グラフを並べて表示する

MAX

棒グラフでグループ毎に値を並べて表示したい場合などがある。

matplotlibだと多少面倒だが、seabornのbarplotの引数hueを使うと、少しデータ整形が必要になるが、簡単にグラフを作成することができる。

ポイントは、hueを使えるようにするために、x軸となる列をインデックスに設定し、並べたい列をstackで積み上げることである。

スポンサーリンク

データ作成

以下のデータを対象とする。

1import pandas as pd
2
3data1 = [30, 35, 40]
4data2 = [24, 28, 31]
5data3 = [20, 25, 25]
6index = ["Aさん", "Bさん", "Cさん"]
7df = pd.DataFrame(data={"額面": data1, "手取り": data2, "支出": data3}, index=index)
8print(df)
9#      額面  手取り  支出
10# Aさん  30     24    20
11# Bさん  35     28    25
12# Cさん  40     31    25

Aさん、Bさん、Cさん毎に、額面、手取り、支出を並べて棒グラフに表示する。

データ整形

seabornのbarplotのhueを指定できるような形に整形する。

一気にやると以下のようなコードになる。

1# 以下の処理を行う
2# stack
3# index名の設定
4# nameの設定
5# reset_index
6
7data = df.stack().rename_axis(["name", "category"]).reset_index().rename(columns={0: "金額(万円)"})
8# 以下のようなコードでも可能
9data = df.stack().rename("金額(万円)").rename_axis(["name", "category"]).reset_index()
10# index名はreset_index前にしておく
11# nameの設定はreset_indexの前後どちらでもOK
12
13print(data)
14#     name   category  金額(万円)
15# 0  Aさん       額面      30
16# 1  Aさん     手取り      24
17# 2  Aさん       支出      20
18# 3  Bさん       額面      35
19# 4  Bさん     手取り      28
20# 5  Bさん       支出      25
21# 6  Cさん       額面      40
22# 7  Cさん     手取り      31
23# 8  Cさん       支出      25

これで、hueにcategoryを指定することで、Aさん、Bさん、Cさん毎に棒グラフを並べて表示することが可能となる。

上記の処理を細かく分解すると以下のようになる。

stackでデータを縦にする

stackでインデックスに対し、列を全て縦にする。

1df.stack()
2# Aさん  額面     30
3#       手取り    24
4#        支出     20
5# Bさん  額面     35
6#       手取り    28
7#        支出     25
8# Cさん  額面     40
9#       手取り    31
10#        支出     25

df.stack()の結果はマルチインデックスのSeriesとなる。

「Aさん、Bさん、Cさん」の列と「額面、手取り、支出」の列は両方ともインデックス列。

数値の列が値の列となる。

列名を全て変更する

rename_axisでインデックス名を変更する。

1df.stack().rename_axis(["name", "category"])
2# name  category
3# Aさん   額面          30
4#        手取り         24
5#         支出          20
6# Bさん   額面          35
7#        手取り         28
8#         支出          25
9# Cさん   額面          40
10#        手取り         31
11#         支出          25

なお、この時もまだ、Seriesであることに注意。

インデックスをリセットする

reset_indexでインデックスを解除する。

1df.stack().rename_axis(["name", "category"]).reset_index()
2#     name   category   0
3# 0  Aさん       額面  30
4# 1  Aさん     手取り  24
5# 2  Aさん       支出  20
6# 3  Bさん       額面  35
7# 4  Bさん     手取り  28
8# 5  Bさん       支出  25
9# 6  Cさん       額面  40
10# 7  Cさん     手取り  31
11# 8  Cさん       支出  25

ここでようやく型がDataFrameになる。

Seriesの時にname属性を設定していない場合、reset_indexすると列名は「0」になる。

値の列名を変更する

「0」となっている列名を変更する。

1df.stack().rename_axis(["name", "category"]).reset_index().rename(columns={0: "金額(万円)"})
2#     name   category  金額(万円)
3# 0  Aさん       額面      30
4# 1  Aさん     手取り      24
5# 2  Aさん       支出      20
6# 3  Bさん       額面      35
7# 4  Bさん     手取り      28
8# 5  Bさん       支出      25
9# 6  Cさん       額面      40
10# 7  Cさん     手取り      31
11# 8  Cさん       支出      25

もちろん、reset_index前のSeriesの状態でnameを設定してから、reset_indexしてもOK。

1df.stack().rename("金額(万円)").rename_axis(["name", "category"]).reset_index()

これで上記と同じ形に整形される。

棒グラフを並べて表示

seabornのbarplotにhueを指定して棒グラフを並べて表示する。

1# 日本語の文字化けを防ぐ
2sns.set(font="meiryo")
3# グラフサイズ設定。
4# facecolor="w"に設定しておくことで、グラフ保存時にグラフ外部分が見えなくなるのを防ぐ。
5plt.figure(figsize=(16, 9), facecolor="w")
6sns.barplot(data=data, x="name", y="金額(万円)", hue="category")
7title = "額面と手取と支出"
8plt.title(title)
9plt.legend(loc="upper left", bbox_to_anchor=(1,1))
10plt.show()

Aさん、Bさん、Cさん毎にまとまって棒グラフが表示される。

スポンサーリンク
ABOUT ME
MAX
MAX
ITエンジニア、データサイエンティスト
新卒でSIerに入社し、フリーランスになってWEB系へ転向。
その後AIの世界へ足を踏み入れ、正社員に戻る。 テーブルデータの分析がメイン。
スポンサーリンク
記事URLをコピーしました