6.4. Seaborn#

Seaborn は、データの可視化に特化したライブラリのひとつで、Matplotlib を補完する役割を担っています。Matplotlib では複雑なコードが必要となるようなグラフも、Seaborn を使えば、シンプルな関数ひとつで手軽に描画できるようになります。また、Seaborn は基本的に Pandas と組み合わせて使用することを想定されており、データの受け渡しは Pandas のデータフレームを通して行うのが一般的です。

6.4.1. Seaborn ライブラリー#

Seaborn ライブラリを利用するには、次のようにインポートします。

import seaborn as sns

なお、Seaborn をインポートすると、Matplotlib の標準設定が Seaborn によって上書きされます。そのため、グラフの色合いや背景などのスタイルが、Seaborn をインポートする前と後で変わる点に注意してください。

6.4.2. データセット#

可視化用にどんぐりのデータセットとタネツケバナの遺伝子発現量データセットを読み込みます。

どんぐりのデータセット(acorns.clean.csv)には、さまざまな種類のどんぐり(樹種)に関する情報が記録されています。各サンプルについて、樹種(tree)、重さ(weight)、高さ(height)、直径(diameter)のデータが記録されています。

# !wget https://py.biopapyrus.jp/data/acorns.clean.csv
acorn_data = pd.read_csv('acorns.clean.csv')
acorn_data.head()
tree weight height diameter
0 kunugi 5.55 2.27 1.89
1 kunugi 4.62 1.98 1.84
2 kunugi 5.05 2.08 1.90
3 kunugi 5.44 2.18 1.91
4 kunugi 5.60 2.20 1.93

タネツケバナの遺伝子発現量データ(cinsueta_exp.csv)は、Cardamine insueta の葉を水面に浮かべたあと、経過時間(0〜96時間)ごとの遺伝子発現量の変化を測定したデータです。

# !wget https://py.biopapyrus.jp/data/cinsueta_exp.csv
exp_data = pd.read_csv('cinsueta_exp.csv', index_col=0)
exp_data = exp_data.reset_index()
exp_data.head()
gene 0h 2h 4h 8h 12h 24h 48h 72h 96h
0 CARHR000010 419 306 1935 2310 2976 242 543 739 402
1 CARHR000060 531 149 981 70 123 348 691 366 160
2 CARHR000090 27 1 0 0 0 0 0 0 0
3 CARHR000110 108 30 93 101 127 55 98 99 75
4 CARHR000120 14 5 0 0 0 0 0 1 0

6.4.3. 基本グラフ#

Seaborn の機能を利用して、散布図や線グラフなどを描く方法を紹介します。まずは、散布図の例です。Seaborn の描画関数は、少なくとも 3 つの引数を取ります。最初にデータセットとしてデータフレーム型のオブジェクトを渡し、次に x 座標と y 座標に対応する列名を指定します。

例えば、散布図を描くには scatterplot 関数を使い、次のように記述します。

sns.scatterplot(acorn_data, x='height', y='weight')
plt.show()
../_images/5eef456b7e8c453e9dbec9f29979db8615c530142a6af8067c44a1b7c6897e25.png

Seaborn の scatterplot 関数では、huestylesize といったオプションを使うことができます。これらにデータフレームの列名を指定すると、点の色(hue)、マーカーの種類(style)、およびサイズ(size)が、その列に書かれたカテゴリごとに自動的に変わります。

また、scatterplot 関数には ax という引数もあり、ここに fig.add_subplot で作成したサブプロット領域を渡すと、その領域内にグラフを描画できます。では、この機能を使って、huestylesize の違いを並べて見てみましょう。

fig = plt.figure()
ax1 = fig.add_subplot(1, 3, 1)
ax2 = fig.add_subplot(1, 3, 2)
ax3 = fig.add_subplot(1, 3, 3)

sns.scatterplot(acorn_data, x='height', y='weight', hue='tree', ax=ax1)
sns.scatterplot(acorn_data, x='height', y='weight', style='tree', ax=ax2)
sns.scatterplot(acorn_data, x='height', y='weight', size='tree', ax=ax3)

plt.show()
../_images/2486619d34fac6ae4850fbfeb6965800c13e4c4da35e5c800785758a9363b1a3.png

次に、遺伝子発現量のデータを使って線グラフを描いてみましょう。exp_data はデータフレーム形式で、各行が遺伝子、各列がストレス処理後の経過時間を表しています。Seaborn で遺伝子ごとの発現量の時系列変化を可視化するには、x 軸および y 軸に対応する情報を列名で指定する必要があります。しかし、現在の exp_data にはそれに該当する列がありません。そのため、データフレームを整形し、遺伝子名と経過時間を示す列を追加します。

exp_data 全体で処理すると、情報量が多くなってしまうため、ここでは最初の 5 つの遺伝子のデータのみを対象に処理を行います。また、ここでグラフが見やすいように、発現量を対数化してから可視化します[1]

exp_data_long = pd.melt(exp_data.iloc[0:5, ], id_vars='gene', var_name='timepoint', value_name='exp')
exp_data_long['log10exp'] = np.log10(exp_data_long['exp'] + 1)
exp_data_long['timepoint'] = exp_data_long['timepoint'].str.replace('h', '').astype(int)
exp_data_long
gene timepoint exp log10exp
0 CARHR000010 0 419 2.623249
1 CARHR000060 0 531 2.725912
2 CARHR000090 0 27 1.447158
3 CARHR000110 0 108 2.037426
4 CARHR000120 0 14 1.176091
5 CARHR000010 2 306 2.487138
6 CARHR000060 2 149 2.176091
7 CARHR000090 2 1 0.301030
8 CARHR000110 2 30 1.491362
9 CARHR000120 2 5 0.778151
10 CARHR000010 4 1935 3.286905
11 CARHR000060 4 981 2.992111
12 CARHR000090 4 0 0.000000
13 CARHR000110 4 93 1.973128
14 CARHR000120 4 0 0.000000
15 CARHR000010 8 2310 3.363800
16 CARHR000060 8 70 1.851258
17 CARHR000090 8 0 0.000000
18 CARHR000110 8 101 2.008600
19 CARHR000120 8 0 0.000000
20 CARHR000010 12 2976 3.473779
21 CARHR000060 12 123 2.093422
22 CARHR000090 12 0 0.000000
23 CARHR000110 12 127 2.107210
24 CARHR000120 12 0 0.000000
25 CARHR000010 24 242 2.385606
26 CARHR000060 24 348 2.542825
27 CARHR000090 24 0 0.000000
28 CARHR000110 24 55 1.748188
29 CARHR000120 24 0 0.000000
30 CARHR000010 48 543 2.735599
31 CARHR000060 48 691 2.840106
32 CARHR000090 48 0 0.000000
33 CARHR000110 48 98 1.995635
34 CARHR000120 48 0 0.000000
35 CARHR000010 72 739 2.869232
36 CARHR000060 72 366 2.564666
37 CARHR000090 72 0 0.000000
38 CARHR000110 72 99 2.000000
39 CARHR000120 72 1 0.301030
40 CARHR000010 96 402 2.605305
41 CARHR000060 96 160 2.206826
42 CARHR000090 96 0 0.000000
43 CARHR000110 96 75 1.880814
44 CARHR000120 96 0 0.000000

整形後のデータを使い、Seaborn の lineplot 関数で遺伝子ごとの発現量の時間変化を描きます。

sns.lineplot(exp_data_long, x='timepoint', y='log10exp', hue='gene')
plt.show()
../_images/07f63c1c455130ee656a414c54f011cc3374f073edb81393f8d7a675951328a8.png

6.4.4. ヒートマップ#

Seaborn の heatmap 関数を使えば、遺伝子発現データのような行列形式のデータから簡単にヒートマップを作成できます。

ここでは、タネツケバナの遺伝子発現量データ exp_data を使い、最初の 5 つの遺伝子の発現量に対してヒートマップを作成します。グラフを見やすくするために、発現量は対数変換(log10)してから可視化します。

expmat = exp_data.iloc[0:5, 1:]
expmat.index = exp_data.iloc[0:5, 0]
expmat = np.log10(expmat + 1)

sns.heatmap(expmat)
plt.show()
../_images/aa50eb4344a1706c1a77f47857bae30316ee29ddcef0ac5b738c117eccf76927.png

heatmap 関数では、さまざまなオプションを指定することで見た目を調整できます。例えば、vmin および vmax は色スケールの最小値・最大値を指定するのに利用します。また、cmap はカラーパレットを指定するのに利用します。'YlGn''viridis''coolwarm' などの Matplotlib で定義されたカラーパレットの名前を指定します。

sns.heatmap(expmat, vmin=0, vmax=5, cmap='YlGn')
plt.show()
../_images/5fd33dba6b23bb0e66b285f910df2baccd0fa78ce04feabb4911b113248221c1.png

より詳しい分析を行いたい場合は、clustermap 関数を使って、行や列を階層的にクラスタリングしたヒートマップを描くことができます。クラスタリングには、距離の定義('euclidean''correlation' など)とクラスタリングアルゴリズム(wardaverage など)を指定します。

sns.clustermap(expmat, metric='euclidean', method='ward',
               vmin=0, vmax=5, cmap='YlGn')
plt.show()
../_images/58b6af409db1610783cc03d0ad8ae250fae000c7e44afd3ad6850e5e07b6626f.png

6.4.5. 多変量データの可視化#

Seaborn には、多変量データの関係性を視覚的に把握できる便利な関数が多数用意されています。ここでは代表的なものをいくつか紹介します。

pairplot 関数を使うと、データフレーム内の数値変数の全ての組み合わせについて散布図を自動的に描画してくれます。また、hue オプションを使えばカテゴリごとに色分けも可能です。データ全体の傾向をざっくり把握したいときに便利です。

sns.pairplot(acorn_data, hue='tree')
plt.show()
../_images/be21d543247540464641182ec0f72539bb6e941eaa237082b57f3c2eb69ed3f2.png

特定の 2 変数間の関係を詳しく見たいときには、jointplot 関数が役立ちます。この関数は、中央に散布図を描き、その周囲に各変数の分布(ヒストグラム)を表示してくれます。

sns.jointplot(acorn_data, x='height', y='weight', hue='tree')
plt.show()
../_images/6344a0961896fbf67fbc2fcef3017b179b91d57c6b2091263ae33d1eb9dc8e5f.png

lmplot 関数は、散布図と共に回帰直線を描画し、さらにその 95% 信頼区間も表示してくれます。2 変数間にどのような傾向があるのかを視覚的に確認するのに適しています。

sns.lmplot(acorn_data, x='height', y='weight', hue='tree')
plt.show()
../_images/82bcab35fdfbecaf5e824c5a82c030600a785d561ff2b11d1ca2533ff6a82e47.png

Seaborn では、上記以外にも多彩なグラフを簡単に作成できます。描きたいグラフがある場合は、Seaborn の公式ドキュメントやインターネットで検索して調べると良いでしょう。ドキュメントには例付きの丁寧な説明が掲載されています。

前節および本節では、Matplotlib や Seaborn を使ったさまざまなデータ可視化の例を紹介しました。グラフはデータを「伝える」ための道具です。適切な可視化を選び、見せたい情報がしっかり伝わるよう心がけましょう。で、ここに書いたことを全部覚えようなんて、さすがに思ってませんよね?正直に言うと、たとえ覚えたとしても数週間後にはほとんど忘れてます。それに、数ヶ月後のライブラリのアップデートであっさり消えてしまうかもしれませんからね。