2020年9月9日にseabornの新バージョンがでましたね
今回はそんなver0.11.0を使いながら可視化の振り返りをしていきます
seaborn公式のギャラリーと関数を参考に全べてのAPIを使ってみたいと思います
可視化だけ興味のある人は真ん中まで飛んでくだし
長いのでctrl + F で検索かけてください
#検証環境
conda create -n eda python==3.8
conda activate eda
notebook==6.1.4
ipykernel==5.3.4
seaborn==0.11.0
pandas==1.1.2
matplotlib==3.3.2
statsmodels==0.12.0
scipy==1.5.2
scikit-learn==0.23.2
numpy==1.19.2
##前のバージョンとの差分
・distributionの可視化コードの見直し
・カラーマップ調整
・dis,hist,ecdf 関数と機能追加
・kde,rug 関数の見直し(statsmodelsが計算していた部分の削除,平滑化がbw_adjによって調節できる,log_scale変換を処理として選択できる)
・jointplotでhistを選択できるようになった
・縦持ち,横持ちデータの両方に対応
・上記 + 細かい変更
私は新バージョン前まで0.10.1を使っていましたが、set_themeとかもいつの間にか追加されていて設定がだいぶ楽になっていました
##アップデートによって非推奨になった項目
・今後distplotがなくなります、dis,hist関数に早いうちに移行してください
#seabornって何ぞ
##seabornについて簡単におさらい
seabornとはmatplotlibのラッパーで、コードを簡単に、そして綺麗な描画をしてくれるパッケージです
背後にはmatplotが動いていますが、だいぶコードの書き方がシンプルになり複雑な図を一行で表現できたりします
いくつかの関数では前処理に似たフィルターや計算も行ってくれることから、EDA用にも適していると感じます
##seabornの思想
seabornの面白い思想を紹介します
seabornはaxes,figureの二つの観点から描画方法を設計しています。
描画する関数のグループ分けは図のようになっており、rel,dis,cat(figure側の関数)によって細かい(axes側の関数による)描画を一括制御することができます。
もちろん個別の関数を呼び出しても使えます。
##細かい関数で描画したほうがスクリプトがわかりやすくない?
一括管理するfigure側の関数では、描画したいキャンバス数を自動的に生成し、グループ分けの処理を行い、描画単位を区切る(facet)ことができます
また、axes側の関数では(指定しなければ)
・軸の名前なども変更し辛い
・凡例を図中に示してしまう
などの問題があります。
figure側の関数であれば軸や判例を別物として扱い、
set_axis_labelsなどを使うことで一行でラベルや判例の制御を簡単に行うことができます。
#そんなことより可視化だ!!
紹介内容を大きく二分割して、
・最初にオプション(色、軸、凡例、等)
・メジャーなfigure側のrel,dis,catをメインで紹介
・発展的な描画を紹介
に分けていきたいと思います
##【opt-0】オプション的な話
オプション的な話を事前に概要だけでも知ってもらうことで、
以降のplotでの話の入ってきやすさを上げておく
そもそも最新版が入っているのか確認しておきましょう
import pandas as pd
from matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
print(sns.__version__)
0.11.0
###【opt-1】データを呼び出す
お手軽に有名なデータを使いたい時
seabornのサポートしているデータはgithub上に保存されているので、
使いたいデータを選びload_datasetで呼び出すことができます
呼び出されたデータはpandasのdataframe形式で操作できます
penguins = sns.load_dataset("penguins")
###【opt-2】描画テーマを設定
現在のテーマを確認しつつ、使いたいテーマを選ぶ
sns.set_theme
<function seaborn.rcmod.set_theme(context='notebook', style='darkgrid', palette='deep', font='sans-serif', font_scale=1, color_codes=True, rc=None)>
styleはグラフ背景の色味を制御します
white, dark, whitegrid, darkgrid
palletはグラフ図形の色パターンを調整します
'Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap',
'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Greens', 'Greens_r', 'Greys', 'Greys_r', 'OrRd', 'OrRd_r',
'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r', 'Paired', 'Paired_r', 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r',
'PiYG', 'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr', 'PuOr_r', 'PuRd', 'PuRd_r', 'Purples',
'Purples_r', 'RdBu', 'RdBu_r', 'RdGy', 'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn', 'RdYlGn_r',
'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', 'Set3', 'Set3_r', 'Spectral', 'Spectral_r', 'Wistia',
'Wistia_r', 'YlGn', 'YlGnBu', 'YlGnBu_r', 'YlGn_r', 'YlOrBr', 'YlOrBr_r', 'YlOrRd', 'YlOrRd_r', 'afmhot',
'afmhot_r', 'autumn', 'autumn_r', 'binary', 'binary_r', 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', 'bwr_r',
'cividis', 'cividis_r', 'cool', 'cool_r', 'coolwarm', 'coolwarm_r', 'copper', 'copper_r', 'crest', 'crest_r',
'cubehelix', 'cubehelix_r', 'flag', 'flag_r', 'flare', 'flare_r', 'gist_earth', 'gist_earth_r', 'gist_gray',
'gist_gray_r', 'gist_heat', 'gist_heat_r', 'gist_ncar', 'gist_ncar_r', 'gist_rainbow', 'gist_rainbow_r',
'gist_stern', 'gist_stern_r', 'gist_yarg', 'gist_yarg_r', 'gnuplot', 'gnuplot2', 'gnuplot2_r', 'gnuplot_r',
'gray', 'gray_r', 'hot', 'hot_r', 'hsv', 'hsv_r', 'icefire', 'icefire_r', 'inferno', 'inferno_r', 'jet',
'jet_r', 'magma', 'magma_r', 'mako', 'mako_r', 'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r',
'pink', 'pink_r', 'plasma', 'plasma_r', 'prism', 'prism_r', 'rainbow', 'rainbow_r', 'rocket', 'rocket_r',
'seismic', 'seismic_r', 'spring', 'spring_r', 'summer', 'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r',
'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'turbo', 'turbo_r', 'twilight',
'twilight_r', 'twilight_shifted', 'twilight_shifted_r', 'viridis', 'viridis_r', 'vlag', 'vlag_r',
'winter', 'winter_r'
sns.set_theme(style="dark",palette='Accent')
df = sns.load_dataset("penguins")
sns.displot(df.flipper_length_mm)
###【opt-3】軸ラベルaxisの変更
g = sns.displot(df.flipper_length_mm)
g.set_axis_labels("Xaxis", "Yaxis")
図形に対して外側から上書きすることができます
軸ラベル回転もできる
g = sns.displot(df.flipper_length_mm)
g.set_axis_labels("Xaxis", "Yaxis")
g.set_xticklabels(rotation=-45)
ラベルの間隔を20刻みに変える場合は
g.set_xticklabels(step=20)
###【opt-4】凡例の描画と色分け
色分けは関数内のhueで指定する
axes関数では
df = sns.load_dataset("iris")
sns.scatterplot(data=df,x='sepal_length',y='sepal_width',hue='species')
凡例が自動的に内側に入ってしまうが、
figure側の関数を使えば自動的に外側に出る
df = sns.load_dataset("iris")
sns.relplot(data=df,x='sepal_length',y='sepal_width',hue='species',kind='scatter')
###【opt-5】複数描画と凡例
散布図を書きたいが、グループごとに散布図を書きたくなることもある
データに対して複数描画するのはFacetGridで実現できる
どの軸でグループ分けするかはcolによって指定する
(colはcolorでなくcolumn)
グループ分けする軸の質的変数の値から描画エリア数は自動的に決めてくれる
df = sns.load_dataset("penguins")
sns.FacetGrid(df,col='species')
作った描画エリアにマッピング(map)していく
df = sns.load_dataset("penguins")
g=sns.FacetGrid(df,col='species')
g.map_dataframe(sns.scatterplot,x='flipper_length_mm',y='bill_depth_mm',hue="sex")
凡例ほしいという時にはadd_legendによって後付けする
df = sns.load_dataset("penguins")
g=sns.FacetGrid(df,col='species')
g.map_dataframe(sns.scatterplot,x='flipper_length_mm',y='bill_depth_mm',hue="sex")
g.set_axis_labels('flipper_length_mm','bill_depth_mm')
g.add_legend()
もう一つ描画の軸を追加したい場合はFacetGridのrowに指定してやれば、さらに分割できる
tips = sns.load_dataset("tips")
g = sns.FacetGrid(tips, col="time", row="sex")
g.map(sns.scatterplot, "total_bill", "tip")
###【opt-6】全体に対してのタイトルが欲しい
各gridでなく全体にタイトルを付ける時はsuptitleで表示する
matplotが後ろで動いてるのでsuptitleも使える
df = sns.load_dataset("penguins")
g=sns.FacetGrid(df,col='species')
g.map_dataframe(sns.scatterplot,x='flipper_length_mm',y='bill_depth_mm',hue="sex")
g.set_axis_labels('flipper_length_mm','bill_depth_mm')
g.add_legend()
g.fig.suptitle('suptitle',y=1.1,x=0,size=18)
###【opt-7】前処理として変数を対数化してほしい
そのままでは値の幅が広すぎてよくわからない
planets = sns.load_dataset("planets")
sns.relplot(data=planets,x="distance", y="orbital_period",hue="year",palette='nipy_spectral')
scaleを指定することで値の前処理をしてくれる
planets = sns.load_dataset("planets")
g=sns.relplot(data=planets,x="distance", y="orbital_period",hue="year",palette='nipy_spectral')
g.set(xscale="log", yscale="log")
###【opt-8】軸の棒を消してほしい
背景gridはテーマで消えるけど、X,Y軸の棒は消えない
sns.set_theme(style="white")
planets = sns.load_dataset("planets")
g=sns.relplot(data=planets,x="distance", y="orbital_period",hue="year",palette='nipy_spectral')
g.set(xscale="log", yscale="log")
despineを使って消す
sns.set_theme(style="white")
planets = sns.load_dataset("planets")
g=sns.relplot(data=planets,x="distance", y="orbital_period",hue="year",palette='nipy_spectral')
g.set(xscale="log", yscale="log")
g.despine(left=True, bottom=True)
###【opt-9】xlimとylimを指定する
sns.set_theme(style="dark",palette='Accent')
df = sns.load_dataset("penguins")
g=sns.displot(df.flipper_length_mm)
g.set(xlim=(0, 300), ylim=(0, 100))
もしくはFacetGrid側で設定する
sns.FacetGrid(df,col='species',xlim=[0,10],ylim=[0,10])
##【main-0】メジャーplot紹介
###【main-1】relplotによるscatterとline
####【main-1.1】デフォルトのrel
sns.set_theme(style="whitegrid")
planets = sns.load_dataset("planets")
g=sns.relplot(data=planets,x="distance", y="orbital_period",palette='Dark2_r')
g.set(xscale="log", yscale="log")
デフォルトで実行した場合scatterになる
sns.set_theme(style="whitegrid")
planets = sns.load_dataset("planets")
g=sns.relplot(data=planets,x="distance", y="orbital_period",palette='Dark2_r',kind='scatter')
g.set(xscale="log", yscale="log")
kindでscatterを指定しても同じ
####【main-1.2】relのkind指定
kindでlineを指定すると点をつないで線形にしてくれる
sns.set_theme(style="whitegrid")
planets = sns.load_dataset("planets")
g=sns.relplot(data=planets,x="distance", y="orbital_period",palette='Dark2_r',kind='line')
g.set(xscale="log", yscale="log")
####【main-1.3】scatterを値に応じてサイズを変える(bubble plot)
散布図の値をbubble plotのように値によって図形を変化させたい
そんなときはsize引数に値の入っているデータ列を指定する
どの程度の大きさにしたいか上限下限をsizesにlistかtupleで渡す
planets = sns.load_dataset("planets")
cmap = sns.cubehelix_palette(rot=-.2, as_cmap=True)
g = sns.relplot(data=planets,x="distance", y="orbital_period",hue="year", size="mass",palette='nipy_spectral', sizes=(10, 300))
g.set(xscale="log", yscale="log")
####【main-1.4】図の出力サイズ変更
出力する図の大きさはheightから操作する
planets = sns.load_dataset("planets")
cmap = sns.cubehelix_palette(rot=-.2, as_cmap=True)
g = sns.relplot(data=planets,x="distance", y="orbital_period",hue="year", size="mass",palette='nipy_spectral', sizes=(10, 300),height=10)
g.set(xscale="log", yscale="log")
####【main-1.5】lineでの信頼区間
散布図で分かりにくいデータも
fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="event",kind='scatter')
lineならわかりやすい
fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="event",kind='line')
信頼区間はciで指定する。
sdか実数を渡すことができ、実数の場合〇%信頼区間を表す
sdは観測地から計算されたsdをそのまま使う
fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="event",kind='line',ci=20)
20%信頼区間に指定した
####【main-1.6】マーカーの指定
イベント点ごとでマーカーを付けたり、信頼区間をエリアでなく棒にすることもできる
sns.relplot(data=fmri, x="timepoint", y="signal", hue="event", err_style="bars", ci=95,markers=True,kind='line')
####【main-1.7】指定した分析軸で線を増やす
先ほど紹介したscatterの時のサイズのように、styleで分析軸をわけることができる
fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="region", style="event",kind='line')
もちろんsizeも指定できる
fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="region", size="event", kind='line')
####【main-1.8】指定した分析軸で画面を分ける
描画画面自体を分けたい場合はcolに分けたい軸を指定する
fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="region", col="event", kind='line')
複数軸での描画の場合、facet_kwsでx軸やy軸のスケールを各図で共有するかどうかを指定できる
fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="region", col="event", kind='line',facet_kws=dict(sharey=False,sharex=False))
ラベル消してビックリグラフにならないように注意
どうしても別の方法で分けたい場合はfigure側の関数でなく、axes側の関数を指定してFacetGridを使うこともできる
fmri = sns.load_dataset("fmri")
g=sns.FacetGrid(fmri,col='event')
g.map_dataframe(sns.lineplot,data=fmri,x='timepoint',y='signal',hue="region")
###【main-2】displotによるhistとkedとecdfとrug
####【main-2.1】displotのデフォルト hist
デフォルトはkind='hist'になっている
penguin = sns.load_dataset("penguins")
sns.displot(data=penguin,x='bill_depth_mm')
#sns.displot(data=penguin,x='bill_depth_mm',kind='hist')
elementという引数で表現方法を変化できる
デフォルトはbar
sns.displot(data=penguin,x='bill_depth_mm',kind='hist',element='poly')
sns.displot(data=penguin,x='bill_depth_mm',kind='hist',element='step')
poly
step
binsで区切る細かさも変えられる
sns.displot(data=penguin,x='bill_depth_mm',kind='hist',element='poly',bins=100)
####【main-2.2】histgramにkde(kernel density estimate)を付け加える
sns.displot(data=penguin,x='bill_depth_mm',kind='hist',kde=True)
もちろんkind='kde'を指定してあげればhistは消える
sns.displot(data=penguin,x='bill_depth_mm',kind='kde')
####【main-2.2】histとkdeの元関数でもplotしてみる
sns.histplot(data=penguin,x='bill_depth_mm')
sns.kdeplot(data=penguin,x='bill_depth_mm')
####【main-2.3】kdeの動きを確認する
平滑化の際にどれだけのデータ幅を見て平滑化するかを決めるbw_adjust
sns.displot(data=penguin,x='bill_depth_mm',kind='kde',bw_adjust=.2)
0.2のとき
100のとき
####【main-2.4】別の軸で色を変える
いつも通り
hueで色分け
colで画面分け
sns.displot(data=penguin,x='bill_depth_mm',kind='kde',hue='sex',col='island')
####【main-2.5】積み上げグラフにする
密度関数を積み上げたい場合はstackを指定する
上に乗っかるだけなので、乗っている側のほうが多いと勘違いしないように注意
histでもkdeでも使える
sns.displot(data=penguin,x='bill_depth_mm',kind='kde',hue='sex',col='island',multiple="stack")
積み上げ時の境界面を消したいときはlinewidth=0を指定する
sns.displot(data=penguin,x='bill_depth_mm',kind='kde',hue='sex',col='island',multiple="stack",linewidth=0)
ほかにもedgecolor="0.1"と指定してあげれば境界線を強めにかいたりできる
積み上げグラフで中の色を抜きたい時にはfillをFalseにする
いよいよ勘違いしそうなグラフになってきた
sns.displot(data=penguin,x='bill_depth_mm',kind='kde',hue='sex',multiple="stack",fill=False)
####【main-2.6】積み上げない、透かしを入れる、alphaについて
alphaを調整することで色の透けを調節できる
sns.displot(data=penguin,x='bill_depth_mm',kind='kde',hue='sex',fill=True,alpha=0.5)
####【main-2.7】multipleについて、面積比として表現する、かぶせ、横に置く
stackでなくfillを指定することで、全体を1とする面積のなかで、どちらの割合が多いかをplotしてくれるようになる
sns.displot(data=penguin,x='bill_depth_mm',kind='kde',hue='sex',multiple="fill")
histで変化を見てみる
sns.displot(data=penguin,x='bill_depth_mm',kind='hist',hue='sex',fill=True,multiple="fill")
sns.displot(data=penguin,x='bill_depth_mm',kind='hist',hue='sex',fill=True,multiple="layer")
sns.displot(data=penguin,x='bill_depth_mm',kind='hist',hue='sex',fill=True,multiple="dodge")
sns.displot(data=penguin,x='bill_depth_mm',kind='hist',hue='sex',fill=True,multiple="stack")
fill
layer
dodge
stack
####【main-2.8】2次元でのplot
histでもkdeでもx,yを指定することで二次元plotにしてくれる
イメージとしては地図の等高線
sns.displot(data=penguin, x="flipper_length_mm", y="bill_length_mm",kind='hist')
sns.displot(data=penguin, x="flipper_length_mm", y="bill_length_mm",kind='kde')
色分けはhue
塗りつぶしはfill
画面分けはcol
という規則に変わりはない
####【main-2.9】2次元での色グラデーション
色のグラデーションを付けたければパターンをcmapに指定して
値の入っていない(確率の低い)ところも塗りつぶすthresh = 0 (1より小さい正の値)
グラデーションの段階の細かさを指定levelsで調整
sns.displot(data=penguin, x="flipper_length_mm", y="bill_length_mm", kind="kde",fill=True, thresh=0, levels=10, cmap='cubehelix')
thresh=0, levels=10
thresh=0.8, levels=10
thresh=0, levels=100
####【main-2.10】rug plotとは
rugとは軸のそばについている細かいヒゲのようなもののこと
kdeで密度を見ながらrugでもどのくらい密集しているのか確認できる
sns.displot(data=penguin, x="flipper_length_mm", y="bill_length_mm", kind="kde", rug=True)
散布図と合わせたりもできる
sns.scatterplot(data=penguin, x="flipper_length_mm", y="bill_length_mm")
sns.rugplot(data=penguin, x="flipper_length_mm", y="bill_length_mm")
####【main-2.11】横向きにplotする
histgramといえばx軸に値の入った積み上げグラフのイメージだが、
yに値を指定することで自動的に横向きに描画してくれる
sns.displot(data=penguin,y='bill_depth_mm',kind='kde',hue='sex',col='island')
####【main-2.12】plotの小タイトルの指定
オプションの時に全体タイトルの話はした
各小タイトルを変えるにはgに一旦グラフ情報を入れてcol_nameからとってくることも可能
(くわしくはset_titlesを参照)
g=sns.displot(data=penguin,y='bill_depth_mm',kind='kde',hue='sex',col='island')
g.set_titles("{col_name} penguins")
####【main-2.13】ecdf累積plot
累積確率として出力できる
sns.displot(data=penguin, x="flipper_length_mm", kind="ecdf")
sns.displot(data=penguin, x="flipper_length_mm", kind="ecdf",complementary=True)
complementary=True
生存時間分析などに使えそう
####【main-2.14】描画画面を複数に分けるcol_wrapと、対数処理をするlog_scale
displotにも内部でlog処理するかを指定できる機能がある
片方の軸だけ対数処理することも可能
描画は普段colで行い自然に分割されるが、
〇列で表示したい等の指定も可能
diamonds = sns.load_dataset("diamonds")
sns.displot(data=diamonds, x="depth", y="price", log_scale=(True, False), col="clarity",col_wrap=5,kind='kde')
###【main-3】catplotによるstrip,swarm,box.box,violin,point,bar,boxen,count
####【main-3.1】catplotのデフォルト
通常ではstripに指定されている
カテゴリーに向いた可視化ツールなので質的変数に対応させる
sns.catplot(data=penguin,x='species',y='bill_depth_mm',height=6,kind='strip')
kindの種類をみていく
sns.catplot(data=penguin,x='species',y='bill_depth_mm',height=6,kind='box')
sns.catplot(data=penguin,x='species',y='bill_depth_mm',height=6,kind='boxen')
sns.catplot(data=penguin,x='species',height=6,kind='count')
sns.catplot(data=penguin,x='species',y='bill_depth_mm',height=6,kind='bar')
sns.catplot(data=penguin,x='species',y='bill_depth_mm',height=6,kind='violin')
sns.catplot(data=penguin,x='species',y='bill_depth_mm',height=6,kind='swarm')
sns.catplot(data=penguin,x='species',y='bill_depth_mm',height=6,kind='point')
box
boxen
count
bar(countのy軸を見る)
violin
swarm
point
群間比較、分散分析などに使えそう
上記を見てもらって信頼区間があるのはわかってもらえたと思う
ciで設定可能
####【main-3.2】boxやviolinの表現
同じ列で描画するか、分けるか dodge
sns.catplot(data=penguin, kind="box",x="species", y="body_mass_g", hue="sex", dodge=False,height=6)
sns.catplot(data=penguin, kind="box",x="species", y="body_mass_g", hue="sex", dodge=True,height=6)
swarmやviolinでも同じ
barでdodgeをFalseにすると混乱を招きそうな図になる
本当は乗っかっているのでなく後ろに隠れている
violinはsplitが選択できる
sns.catplot(data=penguin, kind="violin",x="species", y="body_mass_g", hue="sex", split=True)
yとxを入れ替えて横向きにもできる
sns.catplot(data=penguin, kind="violin",y="species", x="body_mass_g", hue="sex", split=True)
####【main-3.3】swarmとboxやviolin
swarmは点が多くなりやすい
描画できない時、本来描画すべき点ができていないという警告を出してくれる
やさしい
boxやviolinの後から書き足すことで、重ねて表示してくれる機能もある
sns.catplot(data=penguin, kind="box",x="species", y="body_mass_g",height=6)
sns.swarmplot(data=penguin,x="species", y="body_mass_g",hue='sex',palette="Set1")
###【adv】発展的な使い方
####【adv-1】pair plot
データフレーム全体を俯瞰するときに便利なpairを使ってみる
pairplot関数を呼んだ場合、よく見る図となるが
penguin = sns.load_dataset("penguins")
sns.pairplot(penguin)
sns.pairplot(penguin, hue="species)
PairGridを使うと上側、下側のplot形式を改めて指定できる
penguin = sns.load_dataset("penguins")
g = sns.PairGrid(penguin, diag_sharey=False)
g.map_upper(sns.scatterplot, s=15)
g.map_lower(sns.kdeplot)
g.map_diag(sns.kdeplot, lw=2)
####【adv-2】heat map
行列形式のデータに対してheatmapを返す
flights = sns.load_dataset("flights")
flights = flights.pivot("month","year", "passengers")
sns.heatmap(flights)
数値も一緒にのせたい場合はannotをTrueにして、数字が暴れないようにfmtを使う
sns.heatmap(flights, annot=True, fmt="d")
境界を書きたいときにはlinewidthsで指定する
sns.heatmap(flights, linewidths=.5)
numpyの三角行列を作ってくれるtriu_indices_fromを使い、
T,F 1,0で作られたような行列をmaskに入れることで、
形を整えて出力できる
corr = np.corrcoef(np.random.randn(10, 200))
mask = np.zeros_like(corr)
mask[np.triu_indices_from(mask)] = True
with sns.axes_style("white"):
f, ax = plt.subplots(figsize=(7, 5))
ax = sns.heatmap(corr, mask=mask, vmax=.3, square=True)
####【adv-3】joint plot
二つの変数間の関係を密度として見つつ、各変数の分布も確認する
sns.jointplot(x='bill_length_mm', y='bill_depth_mm', data=penguin)
これも種類があってkindで指定することができる
デフォルトの上記はscatter
kde
hist
hex
reg(regression)
residモデル残差確認のためのplot(後述)
jointgridを使うことで組み合わせを考えながらplotすることもできる
メインと側面の図を任意で指定する
g=sns.JointGrid(x='bill_length_mm', y='bill_depth_mm', data=penguin)
g.plot(sns.regplot, sns.kdeplot)
rugの付け足しや、散布図にkdeをかける等を
plot_jointやmarginalsを使って付け足していく
g = sns.jointplot(data=penguin, x="bill_length_mm", y="bill_depth_mm")
g.plot_joint(sns.kdeplot, color="r", zorder=0, levels=6)
g.plot_marginals(sns.rugplot, color="r", height=-.15, clip_on=False)
メイン、上、右の順に指定することで任意の組み合わせをつくる
g = sns.JointGrid()
x, y = penguin["bill_length_mm"], penguin["bill_depth_mm"]
sns.scatterplot(x=x, y=y, ec="b", fc="none", s=100, linewidth=1.5, ax=g.ax_joint)
sns.histplot(x=x, fill=False, linewidth=2, ax=g.ax_marg_x)
sns.kdeplot(y=y, linewidth=2, ax=g.ax_marg_y)
####【adv-4】linear model plot
どうやらFacetとregplotを組み合わせたものがlmplotな様子なので、基本的にlmplotで説明する
pairplotやjointplotで動いているのもregplotらしい
線形回帰を可視化
sns.lmplot(x='bill_length_mm', y='body_mass_g', data=penguin)
hueで色分け
orderで多項式回帰の次数を決める
sns.lmplot(x='bill_length_mm', y='body_mass_g', data=penguin, order=5)
logisticを行うオプションもある
penguin['male'] = pd.get_dummies(penguin.sex)['Male']
sns.lmplot(x='bill_length_mm', y='male',data=penguin, logistic=True)
モデルを作ったら残差も比較したくなる
作図したlmモデル(線形や多項式)がどれだけデータを説明できているのかについては残差確認を行う
線形モデルの判定として、残差が正規分布に従っていそうならばモデルはある程度良いモデルと判定できる
おそらくregとlmの関係からして、
jointplotの"resid"で動いている背景の関数がresidplotかな?
sns.jointplot(x='bill_length_mm', y='body_mass_g', data=penguin,order=1,kind='resid')
sns.jointplot(x='bill_length_mm', y='body_mass_g', data=penguin,order=10,kind='resid')
1次の残差
10次の残差
#####sklearnのモデルと比較
import sklearn
from sklearn import datasets,linear_model
penguin=penguin.dropna(how='any')
model = linear_model.LinearRegression()
X = np.array(penguin["bill_length_mm"]).reshape(-1, 1)
Y = np.array(penguin["body_mass_g"]).reshape(-1, 1)
model.fit(X, Y)
pred_y = model.predict(X)
plt.scatter(x=X, y=Y-pred_y)
たしかに残差を計算してくれていそう。
####【adv-5】clustermap
iris = sns.load_dataset("iris")
species = iris.pop("species")
g = sns.clustermap(iris)
階層クラスタリングを可視化しながらしてくれる
どの距離基準でグループ化していくかはmethodで指定
このあたりは説明しんどいので階層クラスタリングを学んでもらったほうがはやい
methodはscipyの計算から取得scipy.cluster.hierarchy.linkage
mathod
single
complete
average
weighted
centroid
median
ward
single
#最後に
可視化方法はまだまだ紹介していく予定
コードは汚くても間違った図の使い方にはなるべく気を付けたい
#参考
リリースnews-v0.11.0 (September 2020)