見出し画像

Pythonライブラリ(可視化):Seaborn

概要

SeabornはMatplotlibをベースとした可視化ツールです。Matplotlibでは時間がかかるコードを簡単に書けます。詳細は「User guide and tutorial」。
今回はseabornで自分が良く使うメソッドを説明します。

【使用するデータ】
pandasで紹介した2021年8-9月の仮想通貨データを加工(Index:datetime, カテゴリカルデータとしてMonthを追加)しました。

[In]
import pandas as pd

df_Aug = pd.read_csv('Prices_2021_08_20211003_bitFlyer.csv', date_parser=[0]) #2021年8月データ
df_Sep = pd.read_csv('Prices_2021_09_20211003_bitFlyer.csv', date_parser=[0]) #2021年9月データ
df_Aug['Month'] = 'August'
df_Sep['Month'] = 'September'
_df = pd.concat([df_Aug, df_Sep], axis=0) #axis=0は行方向に追加(np.vstack)、axis=1は列方向に追加(np.hstack)
df = _df.iloc[:, :14] #不要なカラムを削除
df['Month'] = _df['Month'] #月情報を追加
df = df.set_index(['Date']) #インデックスをDateに変更
display(df.head())
画像3

1.散布図行列:sns.pairplot()

 sns.pairplot()で散布図行列を作成できます。散布図行列とは複数の変数がある場合に、全ての2変数同士の組み合わせに置いて散布図を作成しそれを行列の形式に並べたものです。
 引数:hueにカテゴリカルデータを渡すとプロットを分類分けできます。

●ヒストグラム:対角線上に配置されておりデータの分布が分かります。
->山が中心にあるため平均的な値で上下してそう
●散布図:各項目の相関関係が確認できます。
->基本的に仮想通貨はどれも同時期に上昇している(DOTが相関が弱いかも)

import seaborn as sns
import matplotlib.pyplot as plt

df_plot = df.loc[:, ['BTC', 'ETH', 'XRP', 'BAT', 'XEM', 'DOT', 'Month']] #見やすいように7次元
sns.pairplot(df_plot, hue='Month')
画像2

さらに細かい体裁修正なら下記引数を追加(一部説明追加)

●Palette:各項目の配色を決める。色は公式を参照
●corner:対角線と逆の図は左右対称になるx軸とy軸が入れ替わった図が作成されるため不要な図を削除
●diag_kind:対角線上の分布表示を変える。‘auto’, ‘hist’, ‘kde’の3種から選択

[In]
sns.pairplot(df_plot, hue='Month', markers=['^', 'o'], palette='coolwarm', #markers->マーカーの形
corner=True , diag_kind="hist", #corner=対象図は表示しない, diag_kind="hist"->histogram、
plot_kws = {'alpha': 0.6, 's': 40, 'edgecolor': 'black'})  #plot_kws:プロットの各種設定(透過度、サイズ、枠線の色)
画像4

2.散布図+ヒストグラムの作成:sns.jointplot()

散布図に加えて枠外にヒストグラムもつけてくれます。

sns.jointplot('BTC', 'ETH', data=df)
plt.show()
画像3

3.散布図:sns.scatterplot()

散布図:sns.scatterplot()はmatplotlibとは異なりx, yに直接データを渡さずに、"data"にデータ、xとyにはカラム名称を渡す。
hueやstyleにカテゴリカルデータを渡すと自動でラベル分けをしてくれる。

[In]
import matplotlib.dates as mdates
fig, ax = plt.subplots(figsize=(16,6))

#x軸の日付表示を1週間単位にする。
weeks = mdates.WeekdayLocator() #週のticksを作成。引数でさらに細かく調整可能
ax.xaxis.set_major_locator(weeks) #x軸にset
ax.tick_params(axis='x', rotation=90) #x軸を90°反転

#散布図 ****ここから下のみseabornの説明
sns.scatterplot(x=df.index, y='BTC', data=df,
            hue='Month',style='Month', s=80)

plt.legend() #凡例
plt.grid() #グリッド線
plt.show()
画像5

4.折れ線図:sns.lineplot()

sns.lineplot()の基本操作はpairplot()やscatterplot()とほぼ同じです。
->参考までにサンプルに1.基準線追加、2.y軸表記を修正しました。

[In]
fig, ax = plt.subplots(figsize=(16,6))

#x軸の日付表示を1週間単位にする。
weeks = mdates.WeekdayLocator() #週のticksを作成。引数でさらに細かく調整可能
ax.xaxis.set_major_locator(weeks) #x軸にset
ax.tick_params(axis='x', rotation=90) #x軸を90°反転

#折れ線図
ax.plot(df.index, [5000000]*len(df), label='5M[JPY]', c='red', ls='dashed')#基準線作成:通常のmatplotlibで作成, lsはlinestyle
sns.lineplot(data=df, x=df.index, y='BTC', 
            hue='Month',style='Month')

# 指数表記から普通の表記に変換
plt.ticklabel_format(style='plain',axis='y') #style='plain':普通の表記, style='sci':指数表記
plt.legend() #凡例
plt.grid() #グリッド線
plt.show()
画像6

5.ヒートマップ:sns.heatmap()

heatmap()は2次元配列の数値の大きさを色で表現します。各通貨の価格トレンドを見るために各項目で平均値を割った値をヒートマップ化しました。

[In]
#各項目のデータを各平均値で割る
df_mean = df.copy()
df_mean = df_mean.iloc[:,:-1]
for column in df_mean.columns:
   df_mean[column] = df_mean[column]/df_mean[column].mean()
  
  
#ヒートマップ作成
plt.figure(figsize=(10,14))
sns.heatmap(df_mean, annot=True, fmt="1.1f", #annot->数値を表示、fmt->annotのフォーマット(1桁表記)
           cmap='rocket', linewidths=0.01) #cmap=パレット選択、linewidths->マップ間に隙間

#シンプル
plt.figure(figsize=(10,14))
sns.heatmap(df_mean , cmap='rocket') #annot->数値を表示、cmap=パレット選択、linewidths->マップ間に隙間 

[Out]
1つ目が左図、シンプル(下)が右図になります。
画像7

【データ確認1:データプロット】
図より、平均値が1.0であり1より薄いと価格が上昇しており濃い黒に近づくと平均値から下がっていることがわかります。右図よりXTZが色の変化がきれいに出ております。プロットで確認しましたが下図の通りBTCより上昇傾向が確認されております。

画像8

【データ確認2:相関関係の可視化】
sns.pairplot()ではプロットで相関関係を可視化しました。df.corr()を使用するとdfの相関値多分決定係数R2を出力できるため、その結果をヒートマップ化します。

[In]
import japanize_matplotlib
fig, ax = plt.subplots(figsize=(7,6))
sns.heatmap(df.corr() , cmap='Blues', annot=True)
plt.title('df.corr()を使用した相関関係ヒートマップ', loc='center', y=-0.2)
画像9

データで見る通り、XTZとDOTは他の通貨とは相関関係が異なりそうです。

6.データの保存

保存はMatplotlibを使用して同じ要領で保存できます。

import matplotlib.pyplot as plt
import seaborn as sns

plt.savefig(ここにファイルパスを記載)

別添1.学習用データセット

 Seabornでは学習用としてトイデータ(少ないデータ数のデータセット)を取得できます。データの種類は公式GitHubでも確認できます。

[IN]
import seaborn as sns

print(sns.get_dataset_names())
for name in sns.get_dataset_names():
    data = sns.load_dataset(name)
    print(name, data.shape)

[OUT]
['anagrams', 'anscombe', 'attention', 'brain_networks', 'car_crashes', 'diamonds', 'dots', 'dowjones', 'exercise', 'flights', 'fmri', 'geyser', 'glue', 'healthexp', 'iris', 'mpg', 'penguins', 'planets', 'seaice', 'taxis', 'tips', 'titanic']

anagrams (20, 5)
anscombe (44, 3)
attention (60, 5)
brain_networks (923, 63)
car_crashes (51, 8)
diamonds (53940, 10)
dots (848, 5)
dowjones (649, 2)
exercise (90, 6)
flights (144, 3)
fmri (1064, 5)
geyser (272, 3)
glue (64, 5)
healthexp (274, 4)
iris (150, 5)
mpg (398, 9)
penguins (344, 7)
planets (1035, 6)
seaice (13175, 2)
taxis (6433, 14)
tips (244, 7)
titanic (891, 15)

参考資料

あとがき

とりあえず自分でも使いたいのですが下書きだと目次が出ないためいったん公開させていただきます。第2段をつくるか、どんどん追加していくかは必要に応じて調整したいです。

それにしてもヒートマップ作った時にannot入れるより何もないほうが直感的に見えるのは面白い!プレゼンとかなら使えそう。






この記事が気に入ったらサポートをしてみませんか?