Seaborn Barplot:Pythonの棒グラフ完全ガイド
Updated on
カテゴリ間の平均値を比較する必要があります。地域別の平均売上、クラスルーム別の平均テストスコア、サーバー別の中央値応答時間かもしれません。生の数値テーブルでは行をスキャンして暗算する必要があります。適切に構築された棒グラフなら、答えが一目で明らかになります -- そしてPythonのseabornライブラリを使えば、たった1回の関数呼び出しで作成できます。
問題は、sns.barplot()が驚くほど多くのパラメータを持っていることです。hueによるグループ化、エラーバーの制御、カテゴリの並べ替え、パレットの選択、水平表示 -- これらのそれぞれが初心者はもちろん、しばらく関数を使っていなかった経験者もつまずかせます。設定が不適切な棒グラフは読者を誤解させるか、単に見栄えが悪くなります。
このガイドでは、sns.barplot()のすべての実用的なユースケースをカバーします。すべてのコードブロックはコピー&ペースト可能で、実際のまたは現実的なデータセットを使用し、きれいな出力を生成します。最後まで読めば、出版品質の棒グラフの作成方法、barplotとcountplotの違い、PyGWalkerを使ったインタラクティブな探索への近道がわかります。
sns.barplot()の機能
sns.barplot()は、各バーの高さ(または長さ)が各カテゴリの数値変数の中心傾向を表す棒グラフを描画します。デフォルトでは平均値を計算し、各バーの上に95%信頼区間をエラーバーとして描画します。
これにより、単純なカウントベースの棒グラフとは異なります。これは統計的な可視化であり、プロットの前にデータを集約します。
基本構文
import seaborn as sns
import matplotlib.pyplot as plt
sns.barplot(data=df, x="category_column", y="numeric_column")
plt.show()主要パラメータの一覧:
| パラメータ | 目的 | デフォルト |
|---|---|---|
data | データを含むDataFrame | 必須 |
x / y | カテゴリ軸と値軸の列名 | 必須 |
hue | 色でバーをグループ化する列 | None |
estimator | 集約関数(平均、中央値、合計など) | mean |
errorbar | エラーバーの種類("ci"、"sd"、"se"、"pi"、またはNone) | ("ci", 95) |
order | 明示的なカテゴリ順序 | None(データ順) |
palette | 配色 | None(seabornデフォルト) |
orient | バーの向き("v"または"h") | 自動検出 |
width | 各バーの幅 | 0.8 |
saturation | 色の彩度レベル | 0.75 |
ax | 描画するMatplotlib Axes | 現在のAxes |
シンプルな縦棒グラフ
組み込みのtipsデータセットから始めましょう。このDataFrameにはレストランの勘定、チップ、顧客属性が記録されています。
import seaborn as sns
import matplotlib.pyplot as plt
tips = sns.load_dataset("tips")
plt.figure(figsize=(8, 5))
sns.barplot(data=tips, x="day", y="total_bill")
plt.title("Average Total Bill by Day")
plt.ylabel("Average Total Bill ($)")
plt.xlabel("Day of Week")
plt.tight_layout()
plt.show()各バーはその日のtotal_billの平均値を示しています。上部の黒い線は95%信頼区間で、平均値がどの程度変動し得るかを示しています。木曜日が最も低い平均勘定額で、日曜日は高い傾向にあります。
集約関数を変更するには、estimatorを渡します:
import numpy as np
sns.barplot(data=tips, x="day", y="total_bill", estimator=np.median)
plt.title("Median Total Bill by Day")
plt.show()水平棒グラフ
水平バーは、カテゴリラベルが長い場合やカテゴリが多い場合に適しています。水平バープロットを作成するには2つの方法があります。
方法1:xとyを入れ替える。
plt.figure(figsize=(8, 5))
sns.barplot(data=tips, x="total_bill", y="day")
plt.title("Average Total Bill by Day (Horizontal)")
plt.xlabel("Average Total Bill ($)")
plt.ylabel("")
plt.tight_layout()
plt.show()数値列がxにあり、カテゴリ列がyにある場合、seabornは自動的に水平バーを描画します。
方法2:orientパラメータを使用する。
sns.barplot(data=tips, x="total_bill", y="day", orient="h")
plt.show()どちらのアプローチも同じ結果を生成します。xとyを入れ替える方がより一般的なパターンです。
グループ化(Hue)棒グラフ
hueパラメータは、2番目のカテゴリ変数に基づいて各カテゴリバーをサブバーに分割します。サブグループを横に並べて比較するのに不可欠です。
plt.figure(figsize=(9, 5))
sns.barplot(data=tips, x="day", y="total_bill", hue="sex")
plt.title("Average Total Bill by Day and Gender")
plt.ylabel("Average Total Bill ($)")
plt.legend(title="Gender")
plt.tight_layout()
plt.show()各曜日に2本のバーが表示されるようになりました -- 男性用と女性用です。凡例は色をグループにマッピングします。ほとんどの日で男性客がわずかに高い平均勘定額を持つ傾向があることがすぐにわかります。
hueレベルが3つ以上の場合、バーは細くなります。可読性が低下する場合は、sns.catplot()によるファセット化アプローチを検討してください:
g = sns.catplot(data=tips, x="day", y="total_bill", hue="sex",
col="time", kind="bar", height=4, aspect=1.2)
g.set_axis_labels("Day", "Average Total Bill ($)")
g.set_titles("{col_name}")
plt.tight_layout()
plt.show()これにより、ランチとディナーの個別パネルが作成され、それぞれ性別でグループ化されたバーが表示されます -- 複数のグループ化次元がある場合にはるかに読みやすくなります。
パレットで色をカスタマイズ
paletteパラメータは配色を制御します。Seabornには多くの組み込みパレットが付属しています。
plt.figure(figsize=(8, 5))
sns.barplot(data=tips, x="day", y="total_bill", hue="sex",
palette="Set2")
plt.title("Custom Palette: Set2")
plt.tight_layout()
plt.show()人気のパレット選択肢:
| パレット | スタイル | 最適な用途 |
|---|---|---|
"Set2" | 落ち着いた、区別しやすい | カテゴリ比較 |
"pastel" | ソフトトーン | プレゼンテーション、明るい背景 |
"deep" | リッチ、飽和 | seabornデフォルトの外観 |
"viridis" | 知覚的に均一 | アクセシビリティ対応 |
"coolwarm" | 発散型の青赤 | 2グループの対比 |
"husl" | 均等に配置された色相 | 多数のカテゴリ |
特定の16進カラーのリストを渡すこともできます:
sns.barplot(data=tips, x="day", y="total_bill",
palette=["#2ecc71", "#e74c3c", "#3498db", "#f39c12"])
plt.show()または辞書を使って特定のカテゴリを色にマッピングします:
day_colors = {"Thur": "#636e72", "Fri": "#e17055",
"Sat": "#0984e3", "Sun": "#6c5ce7"}
sns.barplot(data=tips, x="day", y="total_bill", palette=day_colors)
plt.show()エラーバーと信頼区間
デフォルトでは、sns.barplot()は95%信頼区間を表示します。これは平均値周りのブートストラップCIです。表示内容を完全に制御できます。
import matplotlib.pyplot as plt
import seaborn as sns
tips = sns.load_dataset("tips")
fig, axes = plt.subplots(1, 4, figsize=(18, 4), sharey=True)
# 95% CI (default)
sns.barplot(data=tips, x="day", y="total_bill", errorbar=("ci", 95), ax=axes[0])
axes[0].set_title("95% CI (default)")
# Standard deviation
sns.barplot(data=tips, x="day", y="total_bill", errorbar="sd", ax=axes[1])
axes[1].set_title("Standard Deviation")
# Standard error
sns.barplot(data=tips, x="day", y="total_bill", errorbar="se", ax=axes[2])
axes[2].set_title("Standard Error")
# No error bars
sns.barplot(data=tips, x="day", y="total_bill", errorbar=None, ax=axes[3])
axes[3].set_title("No Error Bars")
plt.tight_layout()
plt.show()| errorbarの値 | 表示内容 | 使用場面 |
|---|---|---|
("ci", 95) | 95%ブートストラップ信頼区間 | デフォルト;統計的推論に適している |
"sd" | 標準偏差 | 推定の不確実性ではなくデータの散布を表示 |
"se" | 平均の標準誤差 | 科学論文で一般的 |
("pi", 95) | 95%パーセンタイル区間 | 観測値の95%をカバーする範囲を表示 |
None | エラーバーなし | 不確実性がフォーカスでない場合のクリーンなビジュアル |
注意: seabornの古いバージョン(0.12より前)では、パラメータは
errorbarではなくciと呼ばれていました。レガシーコードでci=95を見かけた場合、同じことをしています。モダンseabornでは、より柔軟なerrorbarを使用します。
バーの順序付け
デフォルトでは、バーはデータ内のカテゴリの出現順で表示されます。orderパラメータを使用して明示的に制御します。
plt.figure(figsize=(8, 5))
sns.barplot(data=tips, x="day", y="total_bill",
order=["Thur", "Fri", "Sat", "Sun"])
plt.title("Bars in Chronological Order")
plt.tight_layout()
plt.show()バーを値の順序で並べる(大きい順)には、まず平均値を計算します:
day_order = tips.groupby("day")["total_bill"].mean().sort_values(ascending=False).index
plt.figure(figsize=(8, 5))
sns.barplot(data=tips, x="day", y="total_bill", order=day_order)
plt.title("Days Ordered by Average Bill (Descending)")
plt.tight_layout()
plt.show()このパターン -- 集約メトリクスによるソート -- は棒グラフを即座に情報豊富にする最も一般的な方法の1つです。
sns.barplot() vs sns.countplot() -- いつどちらを使うか
この2つの関数は似ていますが、異なる目的を持っています。間違ったものを選択することはよくある混乱の原因です。
| 機能 | sns.barplot() | sns.countplot() |
|---|---|---|
| プロット内容 | カテゴリごとの数値変数の集約メトリクス(平均、中央値、合計) | カテゴリごとの観測数 |
| 数値yが必要か? | はい | いいえ(カテゴリ変数のみ) |
| デフォルト統計量 | 平均値 | カウント |
| エラーバー | あり(デフォルトで信頼区間) | なし |
| ユースケース | 「曜日別の平均チップは?」 | 「各曜日に何食提供された?」 |
| 構文 | sns.barplot(x="day", y="tip", data=tips) | sns.countplot(x="day", data=tips) |
| 同等のもの | df.groupby("day")["tip"].mean()の棒グラフ | df["day"].value_counts()の棒グラフ |
目安: 集約したい数値列がある場合はbarplotを使用します。各カテゴリに何行あるかを数えたいだけの場合はcountplotを使用します。
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# barplot: average tip per day
sns.barplot(data=tips, x="day", y="tip", ax=axes[0])
axes[0].set_title("sns.barplot() -- Average Tip by Day")
axes[0].set_ylabel("Average Tip ($)")
# countplot: number of records per day
sns.countplot(data=tips, x="day", ax=axes[1])
axes[1].set_title("sns.countplot() -- Meals per Day")
axes[1].set_ylabel("Count")
plt.tight_layout()
plt.show()Matplotlibによるカスタマイズ
seabornはmatplotlib上に構築されているため、matplotlibのカスタマイズレイヤーに完全にアクセスできます。タイトルの追加、ラベルの回転、フォントの調整、バーへの注釈はこのようにして行います。
タイトル、ラベル、回転
plt.figure(figsize=(8, 5))
ax = sns.barplot(data=tips, x="day", y="total_bill", palette="muted")
ax.set_title("Average Total Bill by Day", fontsize=16, fontweight="bold")
ax.set_xlabel("Day of the Week", fontsize=12)
ax.set_ylabel("Average Bill ($)", fontsize=12)
ax.tick_params(axis='x', rotation=45)
plt.tight_layout()
plt.show()バーに値ラベルを追加
plt.figure(figsize=(8, 5))
ax = sns.barplot(data=tips, x="day", y="total_bill", errorbar=None,
palette="Blues_d",
order=["Thur", "Fri", "Sat", "Sun"])
# Annotate each bar with its value
for container in ax.containers:
ax.bar_label(container, fmt="%.1f", fontsize=11, padding=3)
ax.set_title("Average Total Bill by Day")
ax.set_ylabel("Average Bill ($)")
ax.set_ylim(0, 25)
plt.tight_layout()
plt.show()ax.bar_label()メソッド(matplotlib 3.4で追加)は、値の注釈を追加する最もクリーンな方法です。padding引数はバー上部からの距離を制御します。
積み上げバー(回避策)
Seabornはネイティブで積み上げ棒グラフをサポートしていません。これは意図的な設計上の決定です -- 積み上げバーは個別のセグメントサイズの比較を困難にします。しかし、ユースケースで必要な場合は、pandasプロッティングまたは手動のmatplotlibアプローチで効果を実現できます。
Pandas .plot(kind="bar", stacked=True)を使用
import pandas as pd
import matplotlib.pyplot as plt
tips = pd.read_csv("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv")
# Pivot to get counts per day and time
pivot = tips.groupby(["day", "time"]).size().unstack(fill_value=0)
# Reorder days
pivot = pivot.loc[["Thur", "Fri", "Sat", "Sun"]]
pivot.plot(kind="bar", stacked=True, figsize=(8, 5),
color=["#3498db", "#e74c3c"], edgecolor="white")
plt.title("Meal Count by Day (Stacked by Lunch/Dinner)")
plt.ylabel("Number of Meals")
plt.xlabel("Day")
plt.xticks(rotation=0)
plt.legend(title="Time")
plt.tight_layout()
plt.show()Matplotlibによる手動積み上げ
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
tips = sns.load_dataset("tips")
pivot = tips.groupby(["day", "time"])["total_bill"].mean().unstack(fill_value=0)
pivot = pivot.loc[["Thur", "Fri", "Sat", "Sun"]]
days = pivot.index
lunch = pivot["Lunch"].values
dinner = pivot["Dinner"].values
x = np.arange(len(days))
width = 0.6
fig, ax = plt.subplots(figsize=(8, 5))
ax.bar(x, lunch, width, label="Lunch", color="#3498db")
ax.bar(x, dinner, width, bottom=lunch, label="Dinner", color="#e74c3c")
ax.set_xticks(x)
ax.set_xticklabels(days)
ax.set_ylabel("Average Total Bill ($)")
ax.set_title("Average Bill by Day (Stacked: Lunch + Dinner)")
ax.legend()
plt.tight_layout()
plt.show()どちらのアプローチも機能します。pandasメソッドはより簡潔です。matplotlibメソッドは配置とスタイリングに対してより多くの制御を提供します。
PyGWalkerでインタラクティブな棒グラフを作成
静的な棒グラフはレポートや論文に最適です。しかし、探索的分析では、軸を変更したり、異なる集約を試したり、データをフィルタリングしたり、チャートタイプを比較したりしたいことがよくあります -- 毎回コードを書き直すことなく。
PyGWalker (opens in a new tab)(Graphic WalkerのPythonバインディング)は、任意のpandas DataFrameをJupyter Notebook内で直接、インタラクティブなTableauのような可視化インターフェースに変換します。フィールドをドラッグ&ドロップすることで、棒グラフ、グループ化棒グラフ、その他数十種類のチャートタイプを構築できます。
pip install pygwalkerimport pandas as pd
import pygwalker as pyg
tips = pd.read_csv("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv")
walker = pyg.walk(tips)インターフェースが読み込まれたら、以下のことができます:
dayをX軸に、total_billをY軸にドラッグして、すぐに棒グラフを作成する。sexまたはtimeをカラーチャネルにドロップして、グループ化棒グラフを取得する。- 集約を平均から合計、中央値、またはカウントにワンクリックで切り替える。
- フィルターを適用する(例:土曜日と日曜日のみ)pandasコードを書かずに。
- 再現性のためにチャート構成をエクスポートする。
これは探索フェーズで特に便利です -- どのグループ化と集約が最も多くのインサイトを明らかにするかを素早くテストし、共有用の最終的な静的可視化をsns.barplot()で確定します。
よくある質問
sns.barplot()で個々のバーの色を変更するには?
paletteパラメータに色のリストを渡します。リストの長さはカテゴリ数と一致する必要があります。例:sns.barplot(data=tips, x="day", y="total_bill", palette=["#e74c3c", "#3498db", "#2ecc71", "#f39c12"])。明示的な制御のために、カテゴリ名を色にマッピングする辞書を渡すこともできます。
sns.barplot()とplt.bar()の違いは?
sns.barplot()はDataFrameと直接連携し、集約統計量(デフォルト:平均)を自動的に計算し、信頼区間を描画します。matplotlibのplt.bar()は事前に計算されたバーの高さと位置が必要で、集約なしで渡されたものをそのまま描画します。迅速な統計的サマリーにはsns.barplot()を、完全な手動制御にはplt.bar()を使用してください。
seaborn barplotからエラーバーを削除するには?
関数呼び出しでerrorbar=Noneを設定します:sns.barplot(data=tips, x="day", y="total_bill", errorbar=None)。seaborn 0.12より前のバージョンでは、代わりにci=Noneを使用します。
sns.barplot()で平均ではなく合計を表示できますか?
はい。関数にestimator=sumを渡します:sns.barplot(data=tips, x="day", y="total_bill", estimator=sum)。配列を受け取ってスカラーを返す任意の関数を使用できます。numpy.median、numpy.std、またはカスタムラムダを含みます。
seabornで水平バープロットを作成するには?
数値列をx軸に、カテゴリ列をyに配置します:sns.barplot(data=tips, x="total_bill", y="day")。Seabornは自動的に向きを検出します。orient="h"を明示的に設定することもできます。
まとめ
seaborn barplotは、Pythonでカテゴリ間の集約メトリクスを可視化する最速の方法です。信頼区間付きの平均値を表示する1行から、hueによるグループ比較、値の注釈付きの完全にスタイル設定されたチャートまで -- sns.barplot()は棒グラフのニーズの全範囲をカバーします。
シンプルに始めましょう:DataFrameを渡し、xとyの列を選び、seabornに集約とスタイリングを任せます。次に、必要に応じてカスタマイズを重ねます -- バーを値でソートしたり、長いラベル用に水平レイアウトに切り替えたり、よりクリーンなプレゼンテーションスライド用にエラーバーをオフにしたり。
積み上げバーが必要な場合は、pandasまたはmatplotlibを直接使用してください。特定のチャート構成にコミットする前にデータをインタラクティブに探索したい場合は、PyGWalker (opens in a new tab)がJupyter内で追加コードなしに動作するドラッグ&ドロップインターフェースを提供します。
このガイドのすべてのコード例はコピーして実行する準備ができています。ユースケースに最も近いパターンを選び、データを入れ替えれば、1分以内にクリアで情報豊富な棒グラフが完成します。