66
84

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

最新のseabornAPIを全て試してデータ可視化スキルを高める【可視化, 2020/9/9-ver0.11.0】

Last updated at Posted at 2020-09-18

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の面白い思想を紹介します

image.png

seabornはaxes,figureの二つの観点から描画方法を設計しています。
描画する関数のグループ分けは図のようになっており、rel,dis,cat(figure側の関数)によって細かい(axes側の関数による)描画を一括制御することができます。
もちろん個別の関数を呼び出しても使えます。

##細かい関数で描画したほうがスクリプトがわかりやすくない?

一括管理するfigure側の関数では、描画したいキャンバス数を自動的に生成し、グループ分けの処理を行い、描画単位を区切る(facet)ことができます

image.png

また、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)

image.png

###【opt-3】軸ラベルaxisの変更

g = sns.displot(df.flipper_length_mm)
g.set_axis_labels("Xaxis", "Yaxis")

image.png

図形に対して外側から上書きすることができます

軸ラベル回転もできる

g = sns.displot(df.flipper_length_mm)
g.set_axis_labels("Xaxis", "Yaxis")
g.set_xticklabels(rotation=-45)

image.png

ラベルの間隔を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')

image.png

凡例が自動的に内側に入ってしまうが、
figure側の関数を使えば自動的に外側に出る

df = sns.load_dataset("iris")
sns.relplot(data=df,x='sepal_length',y='sepal_width',hue='species',kind='scatter')

image.png

###【opt-5】複数描画と凡例

散布図を書きたいが、グループごとに散布図を書きたくなることもある
データに対して複数描画するのはFacetGridで実現できる
どの軸でグループ分けするかはcolによって指定する
(colはcolorでなくcolumn)
グループ分けする軸の質的変数の値から描画エリア数は自動的に決めてくれる

df = sns.load_dataset("penguins")
sns.FacetGrid(df,col='species')

image.png

作った描画エリアにマッピング(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")

image.png

凡例ほしいという時には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()

image.png

もう一つ描画の軸を追加したい場合はFacetGridのrowに指定してやれば、さらに分割できる

tips = sns.load_dataset("tips")

g = sns.FacetGrid(tips, col="time",  row="sex")
g.map(sns.scatterplot, "total_bill", "tip")

image.png

###【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)

image.png

###【opt-7】前処理として変数を対数化してほしい

そのままでは値の幅が広すぎてよくわからない

planets = sns.load_dataset("planets")
sns.relplot(data=planets,x="distance", y="orbital_period",hue="year",palette='nipy_spectral')

image.png

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")

image.png

###【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")

image.png

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)

image.png

###【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))

image.png

もしくはFacetGrid側で設定する

sns.FacetGrid(df,col='species',xlim=[0,10],ylim=[0,10])

image.png

##【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になる

image.png

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を指定しても同じ

image.png

####【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")

image.png

####【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")

image.png

####【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")

image.png

####【main-1.5】lineでの信頼区間

散布図で分かりにくいデータも

fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="event",kind='scatter')

image.png

lineならわかりやすい

fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="event",kind='line')

image.png

信頼区間はciで指定する。
sdか実数を渡すことができ、実数の場合〇%信頼区間を表す
sdは観測地から計算されたsdをそのまま使う

fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="event",kind='line',ci=20)

20%信頼区間に指定した

image.png

####【main-1.6】マーカーの指定

イベント点ごとでマーカーを付けたり、信頼区間をエリアでなく棒にすることもできる

sns.relplot(data=fmri, x="timepoint", y="signal", hue="event", err_style="bars", ci=95,markers=True,kind='line')

image.png

####【main-1.7】指定した分析軸で線を増やす

先ほど紹介したscatterの時のサイズのように、styleで分析軸をわけることができる

fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="region", style="event",kind='line')

image.png

もちろんsizeも指定できる

fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="region", size="event", kind='line')

image.png

####【main-1.8】指定した分析軸で画面を分ける

描画画面自体を分けたい場合はcolに分けたい軸を指定する

fmri = sns.load_dataset("fmri")
sns.relplot(data=fmri,x="timepoint", y="signal", hue="region", col="event", kind='line')

image.png

複数軸での描画の場合、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))

ラベル消してビックリグラフにならないように注意

image.png

どうしても別の方法で分けたい場合は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")

image.png

###【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')

image.png

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

image.png

step

image.png

binsで区切る細かさも変えられる

sns.displot(data=penguin,x='bill_depth_mm',kind='hist',element='poly',bins=100)

image.png

####【main-2.2】histgramにkde(kernel density estimate)を付け加える

sns.displot(data=penguin,x='bill_depth_mm',kind='hist',kde=True)

image.png

もちろんkind='kde'を指定してあげればhistは消える

sns.displot(data=penguin,x='bill_depth_mm',kind='kde')

image.png

####【main-2.2】histとkdeの元関数でもplotしてみる

sns.histplot(data=penguin,x='bill_depth_mm')

image.png

sns.kdeplot(data=penguin,x='bill_depth_mm')

image.png

####【main-2.3】kdeの動きを確認する

平滑化の際にどれだけのデータ幅を見て平滑化するかを決めるbw_adjust

sns.displot(data=penguin,x='bill_depth_mm',kind='kde',bw_adjust=.2)

0.2のとき

image.png

100のとき

image.png

####【main-2.4】別の軸で色を変える

いつも通り
hueで色分け
colで画面分け

sns.displot(data=penguin,x='bill_depth_mm',kind='kde',hue='sex',col='island')

image.png

####【main-2.5】積み上げグラフにする

密度関数を積み上げたい場合はstackを指定する
上に乗っかるだけなので、乗っている側のほうが多いと勘違いしないように注意

histでもkdeでも使える

sns.displot(data=penguin,x='bill_depth_mm',kind='kde',hue='sex',col='island',multiple="stack")

image.png

積み上げ時の境界面を消したいときはlinewidth=0を指定する

sns.displot(data=penguin,x='bill_depth_mm',kind='kde',hue='sex',col='island',multiple="stack",linewidth=0)

image.png

ほかにもedgecolor="0.1"と指定してあげれば境界線を強めにかいたりできる

積み上げグラフで中の色を抜きたい時にはfillをFalseにする
いよいよ勘違いしそうなグラフになってきた

sns.displot(data=penguin,x='bill_depth_mm',kind='kde',hue='sex',multiple="stack",fill=False)

image.png

####【main-2.6】積み上げない、透かしを入れる、alphaについて

alphaを調整することで色の透けを調節できる

sns.displot(data=penguin,x='bill_depth_mm',kind='kde',hue='sex',fill=True,alpha=0.5)

image.png

####【main-2.7】multipleについて、面積比として表現する、かぶせ、横に置く

stackでなくfillを指定することで、全体を1とする面積のなかで、どちらの割合が多いかをplotしてくれるようになる

sns.displot(data=penguin,x='bill_depth_mm',kind='kde',hue='sex',multiple="fill")

image.png

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

image.png

layer

image.png

dodge

image.png

stack

image.png

####【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')

image.png

image.png

色分けはhue
塗りつぶしはfill
画面分けはcol
という規則に変わりはない

image.png

####【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

image.png

thresh=0.8, levels=10

image.png

thresh=0, levels=100

image.png

####【main-2.10】rug plotとは

rugとは軸のそばについている細かいヒゲのようなもののこと
kdeで密度を見ながらrugでもどのくらい密集しているのか確認できる

sns.displot(data=penguin, x="flipper_length_mm", y="bill_length_mm", kind="kde", rug=True)

image.png

散布図と合わせたりもできる

sns.scatterplot(data=penguin, x="flipper_length_mm", y="bill_length_mm")
sns.rugplot(data=penguin, x="flipper_length_mm", y="bill_length_mm")

image.png

####【main-2.11】横向きにplotする

histgramといえばx軸に値の入った積み上げグラフのイメージだが、
yに値を指定することで自動的に横向きに描画してくれる

sns.displot(data=penguin,y='bill_depth_mm',kind='kde',hue='sex',col='island')

image.png

####【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")

image.png

####【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)

image.png

complementary=True

image.png

生存時間分析などに使えそう

####【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')

image.png

###【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')

image.png

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

image.png

boxen

image.png

count

image.png

bar(countのy軸を見る)

image.png

violin

image.png

swarm

image.png

point
群間比較、分散分析などに使えそう

image.png

上記を見てもらって信頼区間があるのはわかってもらえたと思う
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)

image.png

sns.catplot(data=penguin, kind="box",x="species", y="body_mass_g", hue="sex", dodge=True,height=6)

image.png

swarmやviolinでも同じ

image.png

image.png

barでdodgeをFalseにすると混乱を招きそうな図になる

image.png

本当は乗っかっているのでなく後ろに隠れている

image.png

violinはsplitが選択できる

sns.catplot(data=penguin, kind="violin",x="species", y="body_mass_g", hue="sex", split=True)

image.png

yとxを入れ替えて横向きにもできる

sns.catplot(data=penguin, kind="violin",y="species", x="body_mass_g", hue="sex", split=True)

image.png

####【main-3.3】swarmとboxやviolin

swarmは点が多くなりやすい
描画できない時、本来描画すべき点ができていないという警告を出してくれる
やさしい

image.png

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")

image.png

###【adv】発展的な使い方

####【adv-1】pair plot

データフレーム全体を俯瞰するときに便利なpairを使ってみる

pairplot関数を呼んだ場合、よく見る図となるが

penguin = sns.load_dataset("penguins")
sns.pairplot(penguin)

sns.pairplot(penguin, hue="species)

image.png

image.png

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)

image.png

####【adv-2】heat map

行列形式のデータに対してheatmapを返す

flights = sns.load_dataset("flights")
flights = flights.pivot("month","year", "passengers")
sns.heatmap(flights)

image.png

数値も一緒にのせたい場合はannotをTrueにして、数字が暴れないようにfmtを使う

sns.heatmap(flights, annot=True, fmt="d")

image.png

境界を書きたいときにはlinewidthsで指定する

sns.heatmap(flights, linewidths=.5)

image.png

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)

image.png

####【adv-3】joint plot

二つの変数間の関係を密度として見つつ、各変数の分布も確認する

sns.jointplot(x='bill_length_mm', y='bill_depth_mm', data=penguin)

image.png

これも種類があってkindで指定することができる
デフォルトの上記はscatter

kde

image.png

hist

image.png

hex

image.png

reg(regression)

image.png

residモデル残差確認のためのplot(後述)

image.png

jointgridを使うことで組み合わせを考えながらplotすることもできる

メインと側面の図を任意で指定する

g=sns.JointGrid(x='bill_length_mm', y='bill_depth_mm', data=penguin)
g.plot(sns.regplot, sns.kdeplot)

image.png

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)

image.png

メイン、上、右の順に指定することで任意の組み合わせをつくる

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)

image.png

####【adv-4】linear model plot

どうやらFacetとregplotを組み合わせたものがlmplotな様子なので、基本的にlmplotで説明する
pairplotやjointplotで動いているのもregplotらしい

線形回帰を可視化

sns.lmplot(x='bill_length_mm', y='body_mass_g', data=penguin)

image.png

hueで色分け

image.png

orderで多項式回帰の次数を決める

sns.lmplot(x='bill_length_mm', y='body_mass_g', data=penguin, order=5)

image.png

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次の残差

image.png

10次の残差

image.png

#####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)

image.png

たしかに残差を計算してくれていそう。

####【adv-5】clustermap

iris = sns.load_dataset("iris")
species = iris.pop("species")
g = sns.clustermap(iris)

階層クラスタリングを可視化しながらしてくれる
どの距離基準でグループ化していくかはmethodで指定

このあたりは説明しんどいので階層クラスタリングを学んでもらったほうがはやい
methodはscipyの計算から取得scipy.cluster.hierarchy.linkage

image.png

mathod

single
complete
average
weighted
centroid
median
ward

single

image.png

#最後に

可視化方法はまだまだ紹介していく予定
コードは汚くても間違った図の使い方にはなるべく気を付けたい

#参考

リリースnews-v0.11.0 (September 2020)

API reference

Announcing the release of seaborn 0.11

Overview of seaborn plotting functions

66
84
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
66
84

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?