Plotlyの概説と基本的なローカル環境での使い方

plotly example

Pythonでインタラクティブにグラフを扱うことができる代表的なライブラリであるPlotly。
今更ながら、ローカル環境での使用を前提に、基本的な使い方を整理してみました。

注: この記事は2018年12月26日時点の情報に基づいています。

Plotlyとは

Plotlyはオープンソースのライブラリです。
言語としてはPythonだけでなく、RやJavascript, MATLABなどでも提供されています。

コード例

コード量としては少ないので、まずは例を示します。解説は後ほど詳しく行います。
後述しますが、データを外部に送信して利用する側面があるライブラリなので、利用は自己責任でお願いします。
また、オンラインモードとオフラインモードがあるので、使用前に後述する説明部分を読んでいただいた方が良いかと思います。

今回はscikit-learnに入っているbotson_housingデータセットを利用して散布図を作成しています。
コード自体は比較的シンプルです。

import plotly.plotly as py
import plotly.graph_objs as go
import os
from plotly.offline import iplot, init_notebook_mode

# 前提として、boston_dfにboston_housingデータセットの情報が格納されているとします。

init_notebook_mode(connected=True)

x_label = "LSTAT"
y_label = "AGE"

scatter_info = go.Scatter(x=boston_df[x_label], y=boston_df[y_label],
                          mode='markers', name="Plotly Scatter Example")
data = [scatter_info]
layout = dict(title = "Plotly Scatter Example", 
                    xaxis = dict(title=x_label),
                     yaxis=dict(title=y_label))

config={'showLink': False, 'modeBarButtonsToRemove': ['sendDataToCloud','hoverCompareCartesian']}

fig = dict(data = data, layout=layout)
iplot(fig, config=config)

結果のスクリーンショットがこちら。

plotly example

ブログへの結果の埋め込みにはプラグインが必要だったため、
今回は出力代わりにスクリーンショットを添付しています。

参考にしたのは下記の3つのリンクです。
https://plot.ly/python/offline/
https://plot.ly/python/ipython-notebook-tutorial/
https://www.kaggle.com/rtatman/dashboarding-with-notebooks-day-2-python

Jupyter上ではグラフの拡大や、マウスオーバーでデータの詳細の確認などもできます。
参考元にしているいずれのページでも実際に触れるので、一度ご覧いただくとよいと思います。

ちなみに、3つ目のKaggleのリンクは、先日行われていた”Dashboarding with Notebooks”という
5日間の技術紹介シリーズの2日目の資料なので、興味があればそちらも追ってみると学びがあるかと思います。

後述しますが、個人的に重要なポイントは、Notebook上でhelp()を使って関数の使い方を確認することです。
欲しいドキュメントが見つからず、困ったときは是非思い出していただければと思います。

Plotlyの特徴

Plotlyの最大の特徴はご存知の通り、インタラクティブなグラフを作成できることです。

また、作成したグラフをplotlyのサーバーに送信し、ブラウザ上で動くエディタである
”Chart Studio”でグラフの加工や公開ができるようになっていることも大きな特徴です。

これは便利な点でもあるのですが、逆に、外に出してはいけないデータを扱う際は、
誤ってデータを送信してしまわないよう、適切に注意を払う必要があるともいえます。
基本はオフラインモードで使用し、データを送信するボタンを表示しないように設定するのが良いでしょう。

プライバシーに関する問題はやはり心配する声もあるようです。
https://community.plot.ly/t/plotly-privacy-policy/303
調べている限り大丈夫そうですが、不安であれば、そのようなデータには使わないのが最も安全かもしれません。

コードは公開されているので、そちらを読めば確実でしょうか。
現時点ではできていないので、ご利用は自己責任でお願いします。

アカウント登録について

オフラインで使用する分にはアカウントは不要です。

一方、グラフの公開 (Chart Studionでのグラフの保存や埋め込み用のコードの取得など)には
アカウント登録が必要です。

Chart Studio Coludのアカウントは無料版と有料版があります。
また、個人用でない場合はEnterprise版もありますが、ここでは個人用のみを扱います。

無料のアカウントではすべてのグラフが公開され、
有料版にupgradeするとprivateも使用できるようです。

アカウントを作っていない状態でも、グラフのボタンを押すとデータがサーバーに送られ、
Chart Studio上で画面を見ることができます。
公開する場合(埋め込みのコードの取得なども含め)はその際にアカウント登録を求められる流れになっています。

インストール

インストールはpip installで問題ありません。

pip install plotly

などですね。plotly本体だけではあまり引っかからないと思います。
個人的にいくつか引っかかったポイントがあるのですが、一旦ここでは置いておきます。

参考: https://plot.ly/python/getting-started/

コード例と解説

解説のため、先ほどのコードを追っていきます。

今回描画しているデータはscikit-learnのload_bostonを使用しています。
https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_boston.html

データフレームの作成自体は割愛しますが、データフレームは下記のようになっています。

boston_df.head()
CRIMZNINDUSCHASNOXRMAGEDISRADTAXPTRATIOBLSTAT
00.0063218.02.310.00.5386.57565.24.09001.0296.015.3396.904.98
10.027310.07.070.00.4696.42178.94.96712.0242.017.8396.909.14
20.027290.07.070.00.4697.18561.14.96712.0242.017.8392.834.03
30.032370.02.180.00.4586.99845.86.06223.0222.018.7394.632.94
40.069050.02.180.00.4587.14754.26.06223.0222.018.7396.905.33

続いて、先ほどのコードをコメント付きで再掲します。

import plotly.plotly as py
import plotly.graph_objs as go
import os
from plotly.offline import iplot, init_notebook_mode

# 前提として、boston_dfにboston_housingデータセットの情報が格納されているとします。

# plotly.jsをJupyter Notebookで使えるようにする。
init_notebook_mode(connected=True)

# 散布図を作成する対象の洗濯
x_label = "LSTAT"
y_label = "AGE"

# 描画対象の準備
scatter_info = go.Scatter(x=boston_df[x_label], y=boston_df[y_label],
                          mode='markers', name="Plotly Scatter Example")

data = [scatter_info]
layout = dict(title = "Plotly Scatter Example", 
                    xaxis = dict(title=x_label),
                     yaxis=dict(title=y_label))

# plotの際にリンクやボタンを非表示にする (重要)
config={'showLink': False, 'modeBarButtonsToRemove': ['sendDataToCloud','hoverCompareCartesian']}

# plotを行う対象に関する情報を作成
fig = dict(data = data, layout=layout)

# plotを行う部分。
iplot(fig, config=config)

描画のポイント

描画自体のポイントとしては、
– 最終的にiplotに描画対象を持つ辞書と、configのための辞書の2つを渡す。
– 描画対象はグラフオブジェクト (graph_objs)のリストとして渡す。

ということを押さえておくと分かりやすいと思います。

オフラインモードについて

何度かオンライン・オフラインという言葉が出てきていますが、
オフラインモードは手元の環境でPlotlyを使用した描画ができる状態という理解で良いと思います。

PlotlyをNotebook上で使用するためには、jupyterがplotly.jsを使用できる状態になっている必要があります。
この状態を作るために、オフライン環境ではinit_notebook_mode()という関数を使います。

plotly.jsはインターネット経由でロードすることもできるので、
インターネットに繋がっていてもオフラインモードで使用できる、ということは認識しておいても良い気がします。

helpの有効活用

Plotlyを使う上で個人的にかなり重要だったのが、Notebook上でhelp()を使って関数の説明を確認することです。

例えば、

from plotly.offline import iplot, init_notebook_mode
help(init_notebook_mode)

として実行すると、下記のような結果が得られます。


Help on function init_notebook_mode in module plotly.offline.offline: init_notebook_mode(connected=False) Initialize plotly.js in the browser if it hasn't been loaded into the DOM yet. This is an idempotent method and can and should be called from any offline methods that require plotly.js to be loaded into the notebook dom. Keyword arguments: (以下略)

ライブラリを使うときはドキュメントがないと困るのですが、ネットで調べてもなかなか出てこず、苦労しました。

グラフの作り方などの例は非常に充実しているので、そちらは問題ないと思いますが、
知りたい情報が出てこない!というときはhelpを使うことを思い出していただければと思います。

init_notebook_modeについて

オフライン環境で使用する上で重要なポイントは、初めに使っているinit_notebook_modeです。
これは、ブラウザ上での描画に使用しているplotly.jsをロードするために使用しています。
オプションのconnectedは、Trueであればplotly.jsライブラリをCDNからオンラインで取得し、
FalseであればplotlyのPythonパッケージからロードします。

Trueにするメリットはノートブック自体の容量が小さくて済むこと、
デメリットはインターネットに繋がっている必要があることです。

Falseはその逆で、ノートブックの容量は大きくなりますが、
自分だけでなく、ノートブックを見る他の人もインターネットにつながっている環境である必要がないことが挙げられます。

外部にデータを送信するのを避けるための設定

Plotlyで作成したグラフには、Plotlyのサーバーにデータを送るためのリンクになっているボタンが付いています。

その例がこちらです。右下にボタンがある他、右上にも同じ用途で使用することができるボタンがあります。

これらのボタンの表示をさせないために、configにいくつかの設定を入れて対処しています。

とはいえ、不安な場合はやはり外部に出してはいけないデータには使わない方がいいかもしれませんね。

まとめ

今回はPlotlyのオフラインモードを前提とした基本的な使い方を整理しました。
インタラクティブにデータが可視化できるのは、やはり非常に魅力的です。データの扱い等、注意すべき箇所はありますが、自由に使えると効率の良い分析の助けになってくれるのではないでしょうか。

参考資料

https://plot.ly/python/offline/
https://plot.ly/python/ipython-notebook-tutorial/
https://www.kaggle.com/rtatman/dashboarding-with-notebooks-day-2-python
https://plot.ly/python/getting-started/
https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_boston.html