▶ 初学者向けにPythonを使ったデータ分析に役立つ記事を書いています
▶ matplotlibによる可視化を基本から解説しています。以下の投稿も合わせてご覧ください。
はじめに
今回は棒グラフについて基本から解説します。棒グラフは棒の高さで大小を表したグラフです。質的データの値ごとに量的データを比較したり、質的データの数を比較する際に使用します。たとえば、商品ごとの売上を比較したり、男女の数を比較する、などです。比較するときの基本的なグラフなのでしっかりおさえておきましょう。
環境
- Windows11
- Python 3.11.4
- pandas 2.0.3
- numpy: 1.25.0
- matplotlib: 3.7.1
- seaborn: 0.12.2
サンプルデータ
まずはサンプルデータを準備しましょう。今回は前回同様、seabornにあらかじめ用意されている「penguins」データを使うことにしましょう。
import seaborn as sns
import matplotlib.pyplot as plt
import japanize_matplotlib
## ペンギンのデータセットを読み込む
df = sns.load_dataset("penguins")
df.head()
棒グラフの描き方
matplotlibを使って描く
まず基本構文を確認しておきましょう。
xには質的変数、heightには棒の高さにしたい値を設定します。早速やってみましょう。まずは棒グラフを描くためのデータを作りましょう。性別ごとに「body_mass_g」の平均を算出しておきましょう。
# ペンギンの男女別の平均体重
df_body_mass_by_sex = df.groupby('sex')['body_mass_g'].mean()
df_body_mass_by_sex
これを棒グラフで表してみましょう。
# 棒グラフで表す
plt.bar(df_body_mass_by_sex.index, df_body_mass_by_sex)
次に積み上げ棒グラフを描いてみましょう。先にグラフで表したいデータを作っておきましょう。クロス集計表をつくります。
# クロス集計表
pd.crosstab(index=df['sex'], columns=df['island'])
これを積み上げ棒グラフで表してみましょう。
# 積み上げ棒グラフ
x1 = df_by_sex_island.index
y1 = df_by_sex_island['Biscoe']
y2 = df_by_sex_island['Dream']
y3 = df_by_sex_island['Torgersen']
plt.bar(x1, y1, label='Biscoe')
plt.bar(x1, y2, bottom=y1, label='Dream')
plt.bar(x1, y3, bottom=y1+y2, label='Torgersen')
plt.legend()
積み上げ棒グラフを描く際には、ひと工夫必要です。まず積み上げたいデータをy1, y2, y3と分けて置き、それぞれの棒グラフを描いていきます。それぞれの棒グラフを描く際に、y2を描くときにはy1の上に描くのでbottom=y1を指定します。同様に y3を描くときにはy1, y2の上に描くのでbottom=y1+y2を指定します。このように引数bottomでどこに重ねるかを指定して積み上げ棒グラフを作ります。
100%積み上げ棒グラフにするときには、クロス集計表を作るときに標準化すればOKです。次のようにします。
df_by_sex_island_normalize = pd.crosstab(index=df['sex'], columns=df['island'],normalize='index')
# 積み上げ棒グラフ
x1 = df_by_sex_island_normalize.index
y1 = df_by_sex_island_normalize['Biscoe']
y2 = df_by_sex_island_normalize['Dream']
y3 = df_by_sex_island_normalize['Torgersen']
plt.bar(x1, y1, label='Biscoe')
plt.bar(x1, y2, bottom=y1, label='Dream')
plt.bar(x1, y3, bottom=y1+y2, label='Torgersen')
plt.legend()
標準化する際には、pd.crosstab()で引数normalizeでおこないます。’all’ を指定すると全体の合計が1, ’index’を指定すると行方向の合計が1, ’columns’を指定すると列方向の合計が1になります。
seabornを使って描く
こちらもまず、基本構文を確認しておきます。
xには質的データ、yには棒グラフの高さを表すのに使うデータ、dataは対象のデータフレームを指定します。kindで作成するグラフの種類を指定できます。またあ、estimatorは何を推定するかを指定します。defaultは平均値(mean)ですが、ここで関数を指定することができます。
<kindで指定できる値>
・count
質的データの数を高さとした棒グラフを作成する
・bar
xの質的データ毎にyの量的データをもとに指定した演算をして棒グラフを作成する
・point
xの質的データ毎にyの量的データをもとに指定した演算をしてプロットし点を線で繋ぐ
さっそく、グラフを描いていきましょう。まずは、kind=’count’からやってみます。
# カウントプロット
sns.catplot(x='sex', data=df, kind='count')
質的変数の数を数えてその数を棒グラフの高さにするので、yの指定は不要です。簡単に描けます。次に棒グラフを描いてみましょう。棒グラフではyにどのような演算をするのかを指定する必要があります。defaultは平均値なので、今回は指定せずに描いてみましょう。
# seabornで棒グラフを描画
sns.catplot(x='sex',y='body_mass_g', data=df, kind='bar')
こちらも簡単でした!よくみると、棒グラフの上部に縦線がありますね。これはデータの信頼区間を表します。ここでは詳しくは説明しませんが、今回の場合は母集団の平均値が含まれると推定される範囲のことです。この信頼区間が狭いほど、推定値が正確であるといえます。
▶ 信頼区間についてもっと知りたい場合は以下の投稿をご覧ください。
データの信頼区間を非表示にしたい場合は、errorbar=(‘ci’,False)を指定します。ciは、Confidence interval(信頼区間)の意味です。
# 信頼区間を非表示
sns.catplot(x='sex',y='body_mass_g', data=df, kind='bar',errorbar=('ci',False))
このようにseabornで棒グラフを描く場合は、グラフの描画と同時に演算をしてくれるので、matplotlibのときのように事前にデータを処理しておく必要がありません。便利ですね!
積み上げ棒グラフを描く場合は、matplotlibの場合と同様にひと工夫が必要です。次のようにします。
df_by_sex_island = pd.crosstab(index=df['sex'], columns=df['island'])
# 積み上げ棒グラフ
x1 = df_by_sex_island.index
y1 = df_by_sex_island['Biscoe']
y2 = df_by_sex_island['Dream']
y3 = df_by_sex_island['Torgersen']
sns.barplot(x=x1, y=y1, label='Biscoe',color='blue')
sns.barplot(x=x1, y=y2, bottom=y1, label='Dream',color='orange')
sns.barplot(x=x1, y=y3, bottom=y1+y2, label='Torgersen',color='gray')
plt.legend()
100%積み上げ棒グラフを作る場合はmatplotlibで示した場合と全く同様です。クロス集計する際に標準化をしておきます。
seabornでは多くの描画関数でhueという引数をとることができます。これは色相の意味で、指定した質的データで色ごとに描画してくれます。ちょっと見てみましょう。
# 信頼区間を非表示
sns.catplot(x='sex',y='body_mass_g', data=df, hue='species',kind='bar',estimator='sum',errorbar=('ci',False))
このようにsexだけでなく、speciesでも色分けをして棒グラフを描くことができます。seabornでは、簡単な操作で綺麗な描画をすることができます。
pandasのplotで描く
最後にpandasのplot()関数で棒グラフを描く方法です。こちらも書式を確認しておきましょう。
ser(シリーズ)、またはdf(データフレーム)に対してplot関数に引数kind=’bar’を指定することで棒グラフを描くことができます。
ペンギンの男女別の平均体重を棒グラフで描いてみましょう。
# ペンギンの男女別の平均体重
df_body_mass_by_sex = df.groupby('sex')['body_mass_g'].mean()
df_body_mass_by_sex.plot(kind='bar')
次に男女別、island別の集計を描画してみましょう。
df_by_sex_island = pd.crosstab(index=df['sex'], columns=df['island'])
df_by_sex_island.plot(kind='bar')
次にこれを積み上げ棒グラフにしてみましょう。
# 積み上げ棒グラフ
df_by_sex_island.plot(kind='bar',stacked=True)
matplotlib, seabornでは一工夫が必要だった積み上げ棒グラフが一発で描画できます。これ、すごくないですか?stackedにTrueを指定するだけです。
他にもsubplotsにTrueを指定すると、複数のプロットを分離してサブプロットを描くことができます。
# 複数のプロットを分離して描く
df_by_sex_island.plot(kind='bar',subplots=True)
y軸のスケールが揃っていないですね。これを揃えたければ、sharey=Trueを指定します。
df_by_sex_island.plot(kind='bar',subplots=True,sharey=True)
これめっちゃ便利ですね。積み上げ棒グラフや複数のプロットを分けて比較したいときには、pandasのplot関数はめっちゃ便利です。
まとめ
今回は棒グラフの描き方を基本から解説しました。比較の基本となるグラフなのでしっかりおさえておきましょう。このブログではmatplotlib, seabornという可視化ライブラリを使った描画方法に加えて、pandasのplotによる描画も紹介しました。まずは使いやすいものを使う、でよいかと思います。
コメント