Seaborn ボックスプロット:Pythonでボックスプロットを作成・カスタマイズする方法
Updated on
データの分布を理解することは、データ分析における最も基本的なタスクの一つです。モデルを実行したり結論を導き出したりする前に、外れ値を発見し、グループを比較し、歪度を特定する必要があります。しかし、DataFrameの生の数字を見つめているだけでは、全体像を把握することは難しいでしょう。seabornボックスプロットは、分布全体を一目で中央値、広がり、外れ値を示す、コンパクトで読みやすいグラフィックに凝縮することで、この問題を解決します。
このガイドでは、Pythonのseabornライブラリを使用してボックスプロットを作成、カスタマイズ、解釈する方法を学びます。すべてのコード例はseabornに組み込まれた実際のデータセットを使用しているため、Jupyterノートブックですぐに実行できます。
ボックスプロットとは?
ボックスプロット(箱ひげ図とも呼ばれる)は、5つの要約統計量に基づいて分布を表示する標準化された方法です:
| 構成要素 | 表す内容 |
|---|---|
| 中央値の線 | データセットの中央値(第50パーセンタイル) |
| 箱(IQR) | 四分位範囲、Q1(第25パーセンタイル)からQ3(第75パーセンタイル)まで |
| 下ひげ | Q1 - 1.5 * IQR の範囲内の最小データポイント |
| 上ひげ | Q3 + 1.5 * IQR の範囲内の最大データポイント |
| 外れ値ポイント | ひげの範囲外にある個々のデータポイント |
箱はデータの中央50%を捉えます。高い箱は高い変動性を意味し、短い箱は値が密集していることを意味します。中央値の線が箱の中心からずれている場合、分布は歪んでいます。ひげを超える点は、調査に値する潜在的な外れ値を示します。
ボックスプロットは、複数のカテゴリの分布を並べて比較する必要がある場合に特に効果的で、探索的データ分析の定番となっています。
基本的なSeabornボックスプロットの構文
seabornでボックスプロットを作成するには、sns.boxplot()という1つの関数だけが必要です。最低限、データを渡し、プロットする変数を指定します。
import seaborn as sns
import matplotlib.pyplot as plt
# 組み込みデータセットを読み込む
tips = sns.load_dataset("tips")
# 基本的な縦型ボックスプロット
sns.boxplot(data=tips, y="total_bill")
plt.title("合計請求額の分布")
plt.show()これは、total_bill値の分布を示す単一のボックスを生成します。この関数は、四分位数、ひげ、外れ値を自動的に計算します。
カテゴリ変数でデータを分割するには、xパラメータを追加します:
sns.boxplot(data=tips, x="day", y="total_bill")
plt.title("曜日別の合計請求額")
plt.show()これで、4つのボックスが並んで表示され、1週間の支出パターンを簡単に比較できます。
異なるデータ形式からボックスプロットを作成
Seabornは複数のデータ形式を優雅に処理します。以下は最も一般的なシナリオです。
長形式DataFrame(整然データ)
ほとんどのseaborn関数は、各行が単一の観測で列が変数を表す長形式(整然)データで最もよく機能します。tipsデータセットはすでにこの形式になっています:
# 長形式:各行は1回のレストラン訪問
sns.boxplot(data=tips, x="day", y="total_bill")
plt.show()広形式DataFrame
データがグループごとに1列(広形式)の場合でも、seabornは直接ボックスプロットを生成できます:
import pandas as pd
import numpy as np
# 広形式データを作成
np.random.seed(42)
wide_df = pd.DataFrame({
"Group A": np.random.normal(50, 10, 100),
"Group B": np.random.normal(60, 15, 100),
"Group C": np.random.normal(45, 8, 100),
})
sns.boxplot(data=wide_df)
plt.title("3つのグループの比較(広形式データ)")
plt.ylabel("値")
plt.show()Seabornは各列を自動的に別個のカテゴリとして扱い、並べてプロットします。
特定のDataFrame列の選択
より大きなDataFrameから特定の数値列のみを可視化したい場合は、最初にフィルタリングします:
iris = sns.load_dataset("iris")
# 測定列のみを選択
measurement_cols = iris[["sepal_length", "sepal_width", "petal_length", "petal_width"]]
sns.boxplot(data=measurement_cols)
plt.title("アイリス特徴の分布")
plt.xticks(rotation=15)
plt.show()Seabornボックスプロットのカスタマイズ
Seabornは、ボックスプロットの外観と動作を調整するための広範なオプションを提供します。
色とパレット
paletteパラメータを使用して配色を変更するか、すべてのボックスに単一の色を設定します:
# 名前付きパレットを使用
sns.boxplot(data=tips, x="day", y="total_bill", palette="Set2")
plt.title("カスタムパレット")
plt.show()# すべてのボックスに単一の色
sns.boxplot(data=tips, x="day", y="total_bill", color="skyblue")
plt.title("統一色")
plt.show()人気のパレットオプションには、"Set2"、"pastel"、"muted"、"deep"、"husl"、"coolwarm"があります。
水平方向と垂直方向
軸を入れ替えて水平ボックスプロットを作成します。これは、カテゴリラベルが長い場合に便利です:
sns.boxplot(data=tips, x="total_bill", y="day", orient="h")
plt.title("水平ボックスプロット")
plt.show()hueパラメータを使ったグループ化ボックスプロット
hueパラメータは、各カテゴリをサブグループに分割し、比較に第2の次元を追加します:
sns.boxplot(data=tips, x="day", y="total_bill", hue="sex")
plt.title("曜日と性別による合計請求額")
plt.legend(title="性別")
plt.show()各曜日に2つのボックス(性別ごとに1つ)が表示されるようになり、週の各曜日の男性と女性の支出パターンを簡単に比較できます。
図のサイズの制御
Seabornプロットはmatplotlibから図のサイズを継承します。sns.boxplot()を呼び出す前に設定します:
plt.figure(figsize=(12, 6))
sns.boxplot(data=tips, x="day", y="total_bill", hue="smoker", palette="muted")
plt.title("曜日と喫煙状況による合計請求額")
plt.show()スウォームプロットまたはストリッププロットのオーバーレイ追加
ボックスプロットは分布を要約しますが、個々のデータポイントを隠します。すべての観測を表示するには、スウォームプロットまたはストリッププロットをオーバーレイします:
plt.figure(figsize=(10, 6))
sns.boxplot(data=tips, x="day", y="total_bill", palette="pastel")
sns.stripplot(data=tips, x="day", y="total_bill", color="0.3", size=3, jitter=True, alpha=0.5)
plt.title("ストリッププロットオーバーレイ付きボックスプロット")
plt.show()plt.figure(figsize=(10, 6))
sns.boxplot(data=tips, x="day", y="total_bill", palette="pastel")
sns.swarmplot(data=tips, x="day", y="total_bill", color="0.25", size=3, alpha=0.6)
plt.title("スウォームプロットオーバーレイ付きボックスプロット")
plt.show()スウォームプロットはポイントが重ならないように配置し、データ密度をより良く把握できます。データポイントが多い場合はストリッププロットを使用し、少ない場合はスウォームプロットを使用します(スウォームプロットは数千のポイントで遅くなることがあります)。
Seabornボックスプロットパラメータリファレンス
sns.boxplot()で最もよく使用されるパラメータのクイックリファレンスは次のとおりです:
| パラメータ | タイプ | 説明 |
|---|---|---|
data | DataFrame、配列、またはリスト | 入力データ構造 |
x、y | strまたは配列 | 軸の変数 |
hue | str | カラーコードサブグループのグループ化変数 |
order | strのリスト | カテゴリレベルをプロットする順序 |
hue_order | strのリスト | hueレベルの順序 |
orient | "v"または"h" | プロットの向き |
color | str | すべての要素に対する単一の色 |
palette | str、リスト、または辞書 | 異なるレベルの色 |
saturation | float | 元の彩度の比率(0〜1) |
fill | bool | ボックスを色で塗りつぶすかどうか(seaborn >= 0.13) |
width | float | ボックスの幅(デフォルト0.8) |
dodge | bool | カテゴリ軸に沿ってhueグループをシフトするかどうか |
fliersize | float | 外れ値マーカーのサイズ |
linewidth | float | ボックスを囲む線の幅 |
whis | floatまたはタプル | IQRの倍数としてのひげの長さ(デフォルト1.5) |
ax | matplotlib Axes | プロットを描画するAxesオブジェクト |
分布の比較
複数列の並列表示
複数の数値特徴の分布を比較する場合は、DataFrameを長形式に変換します:
iris = sns.load_dataset("iris")
# 広形式から長形式に変換
iris_long = iris.melt(id_vars="species", var_name="measurement", value_name="cm")
plt.figure(figsize=(12, 6))
sns.boxplot(data=iris_long, x="measurement", y="cm", palette="Set3")
plt.title("アイリス測定値の比較")
plt.show()hueを使ったグループ比較
カテゴリとグループ化変数の両方を組み合わせて、2つの次元にわたる分布を比較します:
plt.figure(figsize=(14, 6))
sns.boxplot(data=iris_long, x="measurement", y="cm", hue="species", palette="husl")
plt.title("品種別のアイリス測定値")
plt.legend(title="品種", bbox_to_anchor=(1.05, 1), loc="upper left")
plt.tight_layout()
plt.show()これにより、各測定タイプが3つのボックス(品種ごとに1つ)を示すグループ化ボックスプロットが生成され、品種間の比較が即座に可能になります。
SeabornボックスプロットとMatplotlibボックスプロット
seabornとmatplotlibの両方がボックスプロットを生成できますが、使いやすさと視覚的品質で大きく異なります。
| 機能 | Seaborn sns.boxplot() | Matplotlib ax.boxplot() |
|---|---|---|
| デフォルトの美学 | 洗練され、出版可能 | 基本的、最小限のスタイル |
| DataFrame統合 | pandas DataFrameのネイティブサポート | 手動で配列を抽出する必要がある |
| Hueグループ化 | 組み込みのhueパラメータ | 手動の配置と色付け |
| パレット | 1行でパレット割り当て | 手動のカラーリスト管理 |
| 統計注釈 | スウォーム/ストリッププロットの簡単なオーバーレイ | 手動の散布オーバーレイが必要 |
| カスタマイズの深さ | 中程度(matplotlibに委譲) | 完全な低レベル制御 |
| 学習曲線 | 低い | 中〜高 |
| コードの冗長性 | グループ化プロットで1〜2行 | 同等のもので10〜20行 |
結論:迅速な探索的分析とクリーンなビジュアルにはseabornを使用してください。すべての要素に対してピクセルレベルの制御が必要な場合は、matplotlibにフォールバックします。
# Matplotlibボックスプロット(より冗長)
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(8, 5))
data_by_day = [tips[tips["day"] == d]["total_bill"].values for d in ["Thur", "Fri", "Sat", "Sun"]]
bp = ax.boxplot(data_by_day, labels=["Thur", "Fri", "Sat", "Sun"], patch_artist=True)
for patch, color in zip(bp["boxes"], ["#8dd3c7", "#ffffb3", "#bebada", "#fb8072"]):
patch.set_facecolor(color)
ax.set_title("Matplotlibボックスプロット(手動スタイル)")
ax.set_ylabel("合計請求額")
plt.show()# Seaborn同等品(簡潔)
sns.boxplot(data=tips, x="day", y="total_bill", palette="Set3",
order=["Thur", "Fri", "Sat", "Sun"])
plt.title("Seabornボックスプロット(1行)")
plt.show()ボックスプロット vs バイオリンプロット:どちらを使うべきか
Seabornはsns.violinplot()も提供しており、これは要約統計だけでなく、分布の完全な密度形状を示します。それぞれを選択する場合は次のとおりです:
| 基準 | ボックスプロット | バイオリンプロット |
|---|---|---|
| 最適な用途 | 迅速な要約統計と外れ値検出 | 分布の完全な形状の理解 |
| 外れ値の表示 | はい、個々の点として | いいえ(密度曲線に吸収される) |
| 双峰性の表示 | いいえ | はい(2つの膨らみとして表示) |
| 可読性 | 高い、非技術的な聴衆でも | より多くの説明が必要 |
| スペース効率 | コンパクト | より広く、より多くの水平スペースを取る |
| パフォーマンス | レンダリングが速い | 大規模データセットで遅い(KDE計算) |
経験則:迅速なチェックにはボックスプロットから始めてください。分布に複数のピークや異常な形状があると疑われる場合は、バイオリンプロットに切り替えてください。
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
sns.boxplot(data=tips, x="day", y="total_bill", palette="Set2", ax=axes[0])
axes[0].set_title("ボックスプロット")
sns.violinplot(data=tips, x="day", y="total_bill", palette="Set2", ax=axes[1])
axes[1].set_title("バイオリンプロット")
plt.tight_layout()
plt.show()インタラクティブな代替手段:PyGWalkerで分布を探索
静的なボックスプロットはレポートやノートブックには適していますが、初期の探索フェーズでは、毎回コードを書き直すことなく、異なる変数をチャートに出し入れしたいことがよくあります。
PyGWalker (opens in a new tab)は、Jupyter Notebook内で直接、任意のpandas DataFrameをインタラクティブなTableau風のビジュアル探索インターフェースに変換するオープンソースのPythonライブラリです。フィールドを軸にドラッグするだけで、ボックスプロット、バイオリンプロット、ヒストグラム、散布図などを作成できます。コードの変更は不要です。
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)UIが読み込まれたら、dayをX軸に、total_billをY軸にドラッグし、ボックスプロットマークタイプを選択します。バイオリンプロットに即座に切り替えたり、色の次元を追加したり、任意の列でフィルタリングしたりできます。すべてコードを追加することなく行えます。
これは、全員がPythonを書くわけではないチームにとって特に価値があります。ノートブックを共有し、ステークホルダー自身がデータを探索できるようにします。
| KaggleでPyGWalkerを実行 (opens in a new tab) | Google ColabでPyGWalkerを実行 (opens in a new tab) | GitHubのPyGWalker (opens in a new tab) |
|---|
よくある質問
seabornボックスプロットから外れ値を削除するにはどうすればよいですか?
whisパラメータをより大きな値(例:whis=3.0)に設定して、ひげを延長し、外れ値として表示されるポイントの数を減らします。または、flierprops={"marker": ""}を設定して、ひげの計算を変更せずに外れ値マーカーを完全に非表示にします。
DataFrameを使用せずにseabornボックスプロットをプロットできますか?
はい。生の配列またはリストを直接渡すことができます:sns.boxplot(x=["A"]*50 + ["B"]*50, y=np.random.randn(100))。ただし、軸ラベルが自動的に生成されるため、名前付き列を持つDataFrameを使用することをお勧めします。
sns.boxplotで外れ値マーカーのスタイルを変更するにはどうすればよいですか?
flierpropsパラメータに辞書を渡します:sns.boxplot(data=tips, x="day", y="total_bill", flierprops={"marker": "D", "markerfacecolor": "red", "markersize": 5})。これにより、外れ値マーカーが赤いダイヤモンドに変更されます。
seabornボックスプロットでhueとxの違いは何ですか?
xパラメータは、水平軸上の主要なカテゴリグループを定義します。hueパラメータは、各カテゴリ内に副次的なグループを追加し、並べて配置された色付きボックスとして表示されます。単純な比較にはxのみを使用し、性別やステータスなどの第2変数で各カテゴリを分解する場合はhueを追加します。
seabornボックスプロットをファイルに保存するにはどうすればよいですか?
プロットを作成した後、plt.savefig("boxplot.png", dpi=300, bbox_inches="tight")を呼び出します。Seabornプロットは内部的にはmatplotlibの図であるため、すべてのmatplotlib保存メソッドが機能します。サポートされている形式には、PNG、PDF、SVG、EPSがあります。
まとめ
seabornボックスプロットは、データの分布を理解し、外れ値を発見し、グループを比較するための最も迅速な方法の1つです。sns.boxplot()を使用すると、1行のコードで生のDataFrameから出版可能な品質の可視化を作成できます。hueパラメータは、グループ化された比較を簡単に追加でき、ストリッププロットやスウォームプロットをオーバーレイすることで、ボックスプロットが抽象化する個々のデータポイントの詳細を補完できます。
ノートブックやレポートでの静的分析には、seabornボックスプロットは優れています。pandasデータの上にインタラクティブな探索レイヤーが必要な場合、PyGWalker (opens in a new tab)のようなツールを使用すると、コードの変更なしで可視化を構築および反復できます。
上記の基本的な例から始めて、パレットとオーバーレイを試してみてください。そうすれば、どんなデータ分布の質問にも対応できる信頼できる可視化ツールキットが手に入ります。