6.5. plotly#

Plotly はインタラクティブなグラフを簡単に作成できるライブラリです。Python だけでなく、統計解析に強い R など他の言語からも利用できるため、多くのユーザーに支持されています。数ある可視化ライブラリの中でも、Plotly は一度は触れておく価値のあるツールです。本節では、Plotly を使って基本的なグラフを作成する方法を紹介します。

6.5.1. plotly ライブラリー#

Plotly には主に 2 種類の使用方法があります。一つは、plotly.graph_objects モジュールを利用した方法です。高度なカスタマイズが可能で、柔軟性が高い反面、コード量が多くなりがちです。もう一つが plotly.express モジュールを利用する方法です。少ないコードで手軽にグラフを描けるシンプルなインターフェースです。Seaborn に似ており、データフレームを与えて、列名で x 軸および y 軸を指定して描画します。ここでは、簡潔に使える plotly.express を中心に紹介します。

このモジュールを利用するには次のようにインポートします。

import plotly.express as px

続けて、可視化用にどんぐりのデータセットとタネツケバナの遺伝子発現量データセットを読み込みます。どんぐりのデータセット(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.5.2. 散布図#

Plotly Express では、scatter 関数を使って散布図を描きます。たとえば、どんぐりの高さを x 軸、重さを y 軸としてプロットしたい場合は、次のように書きます。

fig = px.scatter(acorn_data, x='height', y='weight')
fig.show()

また、color オプションにデータフレームの列名を指定することで、点の色をその列のカテゴリや値に応じて自動で変更できます。size オプションを利用すると、各点のサイズも調整可能です。次は、点の色をどんぐりの樹種(tree 列)で変化させ、点のサイズをどんぐりの直径(diameter)に応じて変化させている例です。

fig = px.scatter(acorn_data, x='height', y='weight', color='tree', size='diameter')
fig.show()

6.5.3. 線グラフ#

タネツケバナの遺伝子発現量データを用いて、特定の遺伝子における発現量の時間変化を折れ線グラフで可視化してみましょう。exp_data データフレームは、行に遺伝子、列に時間ごとの発現量が格納された形式になっています。しかし、このままでは x 軸を時間、y 軸を発現量として、列名で指定できません。そこで、以下のように pd.melt 関数を用いてデータフレームの形を変えます。

exp_data_long = pd.melt(exp_data.iloc[0:5, ], id_vars='gene', var_name='timepoint', value_name='exp')

続けて、発現量を対数化し[1]、時間ラベルを整数に変換します。

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

データの整形が完了したら、plotly.expressline 関数を使って、遺伝子ごとの発現変化の時系列変化を折れ線グラフで可視化します。

fig = px.line(exp_data_long, x='timepoint', y='log10exp', color='gene')
fig.show()

6.5.4. 棒グラフ#

どんぐりのデータを使って、樹種ごとの重さの平均を棒グラフにして視覚化する方法を紹介します。まず、acorn_data を樹種(tree)ごとに集計し、それぞれの測定項目の平均値を求めます。

acorn_weight = acorn_data.groupby('tree').agg(np.mean).reset_index()
acorn_weight
tree weight height diameter
0 arakashi 1.487857 1.846429 1.162857
1 konara 1.557000 2.115000 1.108000
2 kunugi 5.521000 2.187000 1.932000
3 matebashii 2.953000 2.699000 1.381000
4 shirakashi 1.806000 1.994667 1.230000

重さ(weight)の平均値を縦棒グラフで可視化します。x 軸に樹種、y 軸に平均重さを指定します。

fig = px.bar(acorn_weight, x='tree', y='weight')
fig.show()

重さ以外の測定項目(height や diameter など)も含めて比較したい場合は、測定項目が列名として指定できるようにデータフレームの形を変更します。

acorn_weight_long = pd.melt(acorn_weight, id_vars='tree', var_name='item', value_name='value')
acorn_weight_long.head()
tree item value
0 arakashi weight 1.487857
1 konara weight 1.557000
2 kunugi weight 5.521000
3 matebashii weight 2.953000
4 shirakashi weight 1.806000

続けて、整形後のデータを使って、item 列の値(重さ、直径、高さなど)ごとに色分けした横並びの棒グラフを描きます。barmode='group' を指定することで、グループごとに棒が並びます。

fig = px.bar(acorn_weight_long, x='tree', y='value', color='item', barmode='group')
fig.show()

なお、barmode を省略した場合は、積み上げ棒グラフが描かれます。

fig = px.bar(acorn_weight_long, x='tree', y='value', color='item')
fig.show()

6.5.5. ヒストグラム#

histogram 関数を使うと、数値データの分布をヒストグラムで可視化できます。たとえば、どんぐりの重さ(weight)の分布を表示するには、次のように書きます。

fig = px.histogram(acorn_data, x='weight')
fig.show()

color オプションを使うと、どんぐりの樹種(tree)ごとに色分けしたヒストグラムを描くことができます。複数個のヒストグラムがある場合、barmode='overlay' を使うことで、重ねて表示されるようになります。また、nbins でビン(棒)の数を指定することができます。

fig = px.histogram(acorn_data, x='weight', color='tree', nbins=20, barmode='overlay')
fig.show()

histogram 関数の marginal オプションを使えば、ヒストグラムの上部にボックスプロットを追加することができます。マウスをボックスプロットに載せると、各種の要約統計量を確認することができます。

fig = px.histogram(acorn_data, x='weight', color='tree', nbins=20, barmode='overlay', marginal='box')
fig.show()