統計で例として使うデータとしては、昔はあやめ(iris)のデータが有名でしたが、それに代わるものとして、palmerpenguins というデータが提案されています。これは南極のパーマーランドの三つの島に住むペンギンたちのデータです。
データは、ここでは seaborn のものを使います:
import seaborn as sns penguins = sns.load_dataset("penguins") penguins
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex 0 Adelie Torgersen 39.1 18.7 181.0 3750.0 Male 1 Adelie Torgersen 39.5 17.4 186.0 3800.0 Female 2 Adelie Torgersen 40.3 18.0 195.0 3250.0 Female 3 Adelie Torgersen NaN NaN NaN NaN NaN 4 Adelie Torgersen 36.7 19.3 193.0 3450.0 Female .. ... ... ... ... ... ... ... 339 Gentoo Biscoe NaN NaN NaN NaN NaN 340 Gentoo Biscoe 46.8 14.3 215.0 4850.0 Female 341 Gentoo Biscoe 50.4 15.7 222.0 5750.0 Male 342 Gentoo Biscoe 45.2 14.8 212.0 5200.0 Female 343 Gentoo Biscoe 49.9 16.1 213.0 5400.0 Male [344 rows x 7 columns]
penguins.value_counts("species")
species Adelie 152 Gentoo 124 Chinstrap 68 dtype: int64
penguins.value_counts("island")
island Biscoe 168 Dream 124 Torgersen 52 dtype: int64
パーマーペンギンには Adelie(Adélie、アデリーペンギン)、Gentoo(ジェンツーペンギン)、Chinstrap(ヒゲペンギン)という種類があります。島の名前は Biscoe(ビスコー)、Dream(ドリーム)、Torgersen(トージャーセン)です。
変数名は、species(種)、island(島)、bill_length_mm(くちばしの長さmm)、bill_depth_mm(くちばしの上下幅mm)、flipper_length_mm(ひれの長さmm)、body_mass_g(体重g)、sex(性別、Male=オス、Female=メス)です。
箱ひげ図を描いてみましょう:
sns.boxplot(x="species", y="body_mass_g", data=penguins)
箱ひげ図は、コンピュータグラフィックスがあまり進んでいない1970年代に、John Tukey によって提案されて普及したものです。今なら、同じスペースを使って、より多くの情報を表示することができます。
例えば、図の幅を少し狭くして、箱ひげ図の色を白にし、外れ値を非表示にして、上からストリッププロット(左右にランダムなジッターを加えたドットプロット)をかぶせてみましょう:
plt.figure(figsize=(4.0, 4.8)) sns.boxplot(x="species", y="body_mass_g", data=penguins, color="white", fliersize=0) sns.stripplot(x="species", y="body_mass_g", data=penguins)
sns.boxplot()
や sns.stripplot()
の代わりに sns.violinplot()
、sns.swarmplot()
とすると、バイオリンプロットやスウォームプロットが得られます。
sns.violinplot(x="species", y="body_mass_g", data=penguins)
sns.swarmplot(x="species", y="body_mass_g", data=penguins)
また、pip install git+https://github.com/mparker2/seaborn_sinaplot.git
してインポートすれば、シーナプロット sinaplot.sinaplot()
も使えます:
[追記] seabornの新しいバージョンでは使えなくなっているようです。とりあえず作者に issue を送っておきましたが、なかなか対応してもらえないようです。とりあえず独自実装の簡単な関数を作っておきました。
import sinaplot sinaplot.sinaplot(x="species", y="body_mass_g", data=penguins)
ちなみに、箱ひげ図を Matplotlib だけでするなら、次のようになります:
x1 = penguins.query("species == 'Adelie'")["body_mass_g"].dropna() x2 = penguins.query("species == 'Chinstrap'")["body_mass_g"].dropna() x3 = penguins.query("species == 'Gentoo'")["body_mass_g"].dropna() plt.boxplot([x1, x2, x3], labels=["Adelie", "Chinstrap", "Gentoo"]) plt.ylabel("Body Mass (g)")
この最初の4行は次のように書くこともできます:
s = penguins["species"].unique() # ["Adelie", "Chinstrap", "Gentoo"] x = [penguins.query(f"species == '{i}'")["body_mass_g"].dropna() for i in s] plt.boxplot(x, labels=s)
中央値がオレンジになるのが嫌なら plt.boxplot()
に medianprops=dict(color="black")
というオプションを入れます。