Skip to content
トピック
Seaborn
Seaborn ボックスプロット:Pythonでボックスプロットを作成・カスタマイズする方法

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()で最もよく使用されるパラメータのクイックリファレンスは次のとおりです:

パラメータタイプ説明
dataDataFrame、配列、またはリスト入力データ構造
xystrまたは配列軸の変数
huestrカラーコードサブグループのグループ化変数
orderstrのリストカテゴリレベルをプロットする順序
hue_orderstrのリストhueレベルの順序
orient"v"または"h"プロットの向き
colorstrすべての要素に対する単一の色
palettestr、リスト、または辞書異なるレベルの色
saturationfloat元の彩度の比率(0〜1)
fillboolボックスを色で塗りつぶすかどうか(seaborn >= 0.13)
widthfloatボックスの幅(デフォルト0.8)
dodgeboolカテゴリ軸に沿ってhueグループをシフトするかどうか
fliersizefloat外れ値マーカーのサイズ
linewidthfloatボックスを囲む線の幅
whisfloatまたはタプルIQRの倍数としてのひげの長さ(デフォルト1.5)
axmatplotlib 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 pygwalker
import 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)のようなツールを使用すると、コードの変更なしで可視化を構築および反復できます。

上記の基本的な例から始めて、パレットとオーバーレイを試してみてください。そうすれば、どんなデータ分布の質問にも対応できる信頼できる可視化ツールキットが手に入ります。

📚