PtitPrinceによるPythonでのRaincloud plotの描画
Raincloud plotを描画するときにPtitPrinceを使うことがあるのですが、日本語のメモが無かったので書きました。
Raincloud plotとは¶
Raincloud plotは簡単に言えば生データ (strip plot), 箱ひげ図 (box plot), バイオリン図 (violin plot)を見やすく組み合わせたデータの描画手法である。Micah Allen氏のIntroducing Raincloud Plots!というブログで初めに提案され、その後論文にもなっている (Allen et al., Wellcome Open Res. 2019)。
Allen M, Poggiali D, Whitaker K, Marshall TR, Kievit RA. Raincloud plots: a multi-platform tool for robust data visualization. Wellcome Open Res. 2019 Apr 1;4:63. doi: 10.12688/wellcomeopenres.15191.1. PMID: 31069261; PMCID: PMC6480976.
この論文に付属して、以下のリポジトリにR, PythonおよびMatlabでRaincloud plotを描画するtutorialがまとめられている。
上記のリポジトリを参考にして、Raincloud plotをseabornのviolin plotなどと同様に描画できるようなライブラリにしたのがPtitPrinceである。
# !pip install ptitprince
import ptitprince as pt
ライブラリとサンプルデータセットのload¶
ptitprince
の他にpandas
, seaborn
, matplotlib
を用いる。
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
tips = sns.load_dataset("tips")
print(tips.shape)
描画例のためにseaborn
のtips データセットを用いる。初めの5列を見てみよう。
tips.head()
pt.RainCloud
関数¶
引数の概要¶
以下はhelp(pt.RainCloud)
で表示できる内容の一部を適宜訳したもの。
RainCloud(x=None, y=None, hue=None, data=None, order=None, hue_order=None, orient='v', width_viol=0.7, width_box=0.15, palette='Set2', bw=0.2, linewidth=1, cut=0.0, scale='area', jitter=1, move=0.0, offset=None, point_size=3, ax=None, pointplot=False, alpha=None, dodge=False, linecolor='red', **kwargs)
異なるカテゴリx
の尺度y
のRaincloud plotを描画する。ただし、x
とy
はpandas dataframe のdata
の異なる列である。
主な入力:
x
: categorical data. Iterable, np.array, or dataframe column name ifdata
is specifiedy
: measure data. Iterable, np.array, or dataframe column name ifdata
is specifiedhue
: a second categorical data. Use it to obtain different clouds and rainpointsdata
: input pandas dataframeorder
: list, order of the categorical datahue_order
: list, order of the hueorient
: string, vertical if"v"
(default), horizontal if"h"
width_viol
: float, width of the cloudwidth_box
: float, width of the boxplotmove
: float, adjusts rain position to the x-axis (default value 0.)offset
: float, adjusts cloud position to the x-axis
kwargsは、cloud (default), boxplot, rain/stripplot, pointplotのそれぞれについてキーワード引数の頭に [cloud_, box_, rain_, point_]
を付けることで指定ができる。例えば stripplotはrain
であり、edgecolor
を変更したければ頭にrain_
を付けてrain_edgecolor="gray"
などとする。
描画例とRaincloud plotについて¶
pt.RainCloud
関数を使ってRainCloud plotを描画してみよう。
pt.RainCloud(x="time", y="tip", data=tips, orient="h", pointplot=True)
plt.tight_layout()
ただし、"RainCloud"「雨雲」と呼ばれる理由が分かりやすいように描画方向を水平向きにした。RainCloud plotは以下の4つの構成要素から成る。
- 「雲」("Cloud"):カーネル密度推定 (あるいはhalf violinplot)
- 「雨」("Rain"):雲の下の stripplot
- 「傘」("Umberella"):箱ひげ図 (boxplot)
- 「雷」("Thunder"):異なる群の平均値を結ぶ pointplot (
pointplot=True
の場合)
しかし、わざわざRainCloud plotを導入しなくても生データ(strip plot), 箱ひげ図(box plot), バイオリン図(violin plot)の組み合わせであればsns.violinplot
とsns.stripplot
でも実現可能である。比較のために描画してみよう。
sns.violinplot(y="time", x="tip", data=tips, orient="h", color=".8", bw=0.2)
sns.stripplot(y="time", x="tip", data=tips, orient="h", alpha=.7)
plt.tight_layout()
箱ひげ図とstrip plotが被り見にくいことが分かる。violin plotは左右対称だがこれは冗長な表現とも言えるので、片側だけ表示し、箱ひげ図を横にずらして見やすくしたのがRainCloud plotである。
描画向きを変える¶
orient="v"
とすれば垂直に、orient="h"
とすれば水平に描画される。デフォルトは"v"
である。
plt.figure(figsize=(10, 4))
plt.subplot(1,2,1); plt.title("vertical")
pt.RainCloud(x="day", y="total_bill", data=tips, orient="v")
plt.subplot(1,2,2); plt.title("horizontal")
pt.RainCloud(x="day", y="total_bill", data=tips, orient="h")
plt.tight_layout()
片側violin plot ("cloud") を調整する¶
width_viol
で横幅、bw
でカーネルのバンド幅、linewidth
で輪郭線の太さが調整できる。
plt.figure(figsize=(12, 4))
plt.subplot(1,3,1); plt.title("width_viol=0.3")
pt.RainCloud(x="day", y="total_bill", data=tips, width_viol=0.3)
plt.subplot(1,3,2); plt.title("width_viol=0.3, bw=1")
pt.RainCloud(x="day", y="total_bill", data=tips, width_viol=0.3, bw=1)
plt.subplot(1,3,3); plt.title("linewidth=3")
pt.RainCloud(x="day", y="total_bill", data=tips, linewidth=3)
plt.tight_layout()
stripplot ("rain") を調整する¶
point_size
で点の大きさ、jitter
で点のばらつきの大きさが調整できる。また、キーワード引数の頭にrain_
を付けてrain_edgecolor
で輪郭線の色, rain_linewidth
で輪郭線の幅, rain_alpha
で点の透過度が調整できる。
plt.figure(figsize=(12, 4))
plt.subplot(1,3,1); plt.title("point_size=8")
pt.RainCloud(x="day", y="total_bill", data=tips, point_size=8)
plt.subplot(1,3,2); plt.title("jitter=.01")
pt.RainCloud(x="day", y="total_bill", data=tips, jitter=.01)
plt.subplot(1,3,3); plt.title("rain_edgecolor='gray', \n rain_linewidth=1, rain_alpha=0.5")
pt.RainCloud(x="day", y="total_bill", data=tips, point_size=8,
rain_edgecolor='gray', rain_linewidth=1, rain_alpha=0.5)
plt.tight_layout()
箱ひげ図 ("umberella") を調整する¶
width_box
で箱ひげ図の幅、box_linewidth
で箱ひげ図の線の太さが調整できる。
plt.figure(figsize=(8, 4))
plt.subplot(1,2,1); plt.title("width_box=0.3")
pt.RainCloud(x="day", y="total_bill", data=tips, width_viol=0.5, width_box=0.3)
plt.tight_layout()
plt.subplot(1,2,2); plt.title("box_linewidth=3")
pt.RainCloud(x="day", y="total_bill", data=tips, box_linewidth=3)
plt.tight_layout()
平均値を結ぶ線 ("thunder") を調整する¶
pointplot=True
とすれば平均値を結ぶ線が描画される。defaultの色は赤だが,linecolor
の引数を指定することで色を変更できる。
plt.figure(figsize=(12, 4))
plt.subplot(1,3,1); plt.title("pointplot=True")
pt.RainCloud(x="day", y="total_bill", data=tips, pointplot=True)
plt.subplot(1,3,2); plt.title("linecolor='tab:blue'")
pt.RainCloud(x="day", y="total_bill", data=tips, pointplot=True, linecolor='tab:blue')
plt.subplot(1,3,3); plt.title("point_linestyles='--'")
pt.RainCloud(x="day", y="total_bill", data=tips, pointplot=True, point_linestyles='--')
plt.tight_layout()
各グループでの比較¶
hue
を指定することで2つ目のカテゴリについての比較もできる。ここでは同様のことが可能なviolin plotの場合との比較をしている。なお、alpha
に[0, 1]の数字を与えることで全体の透過度を変更できる。右上図では箱ひげ図の位置が被っており見にくい。このような場合はdodge = True
とすれば箱ひげ図の位置をずらすことができる。さらにpointplot=True
としたのが左下図である。
plt.figure(figsize=(12, 8))
plt.subplot(2,2,1); plt.title("sns.violinplot")
sns.violinplot(x="day", y="total_bill", hue="smoker", data=tips, palette='Set2', bw=.2)
plt.subplot(2,2,2); plt.title("pt.RainCloud")
pt.RainCloud(x="day", y="total_bill", hue="smoker", data=tips, alpha=.65)
plt.subplot(2,2,3); plt.title("pt.RainCloud (dodge=True, pointplot=True)")
pt.RainCloud(x="day", y="total_bill", hue="smoker", data=tips, alpha=.65, dodge=True, pointplot=True)
plt.tight_layout()
pt.half_violinplot
関数¶
恐らく使う機会はあまりないだろうが、pt.half_violinplot
というviolin plotの片側のみを描画する関数も用意されている。
half_violinplot(x=None, y=None, hue=None, data=None, order=None, hue_order=None, bw='scott', cut=2, scale='area', scale_hue=True, gridsize=100, width=0.8, inner='box', split=False, dodge=True, orient=None, linewidth=None, color=None, palette=None, saturation=0.75, ax=None, offset=0.15, **kwargs)
pt.half_violinplot(x="day", y="total_bill", data=tips, palette="Set2", width=0.5, bw=0.3)
plt.tight_layout()
まとめ¶
- Raincloud plotは生データとその分布を描画するのに優れた手法である。
- PtitPrinceというライブラリを用いればPythonでRaincloud plotを簡単に描画できる。
- 前の記事 : 仮説に基づいたデータ解析における先入観の弊害
- 次の記事 : 行列方程式のクロネッカー積による解法
- 関連記事 :