Jupyter/Python上でたった3行でインタラクティブなチャート・ウィジェットを作れる！PixieDustを触ってみた


![image](https://qiita-image-store.s3.amazonaws.com/0/108535/4ae9afc6-2865-0123-3b94-0ad75c29978b.png)

# TL;DR
Python環境で`pip install pixiedust`でインストール後、Jupyter起動してこの3行書くだけで

```py
import pixiedust
df = pixiedust.sampleData(Data-URL) # pandas or Spark Dataframe
display(df)
```

こんなウイジェットができて対話式にデータを分析できます。簡単すぎ！
![Pixiedust-001.gif](https://qiita-image-store.s3.amazonaws.com/0/108535/143dfa8c-4746-1f29-d839-8da38428b7c5.gif)


# PixieDustって何?

PixieDustは簡単ですけど結構機能が広いライブラリーなので、ざっくり概要=What isは「[Jupyter/Pythonでデータ分析する人にお勧めしたい！便利なライブラリー 「PixieDust」をザクッと紹介します](https://qiita.com/ishida330/items/53f1b0df2247fab5c6dd)」の記事に書きました。ご興味あればそちらをご参照ください。当記事はインタラクティブなチャート・ウィジェット周りの使い方(How-To)にフォーカスします。

# まずはAPIを2つ知ってれば十分
Pixiedustで主に知っている必要がある**APIは基本、2つだけ**です.

1. データをインポートするための**sampleData(URL)**  - 利用は任意
2. データを可視化するための**display(df)**  -  必須

しかありません。ややこしいパラメータも殆どありません。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/76a706c3-1982-58c2-64af-1cb7aa785929.png)

- PixieDustは**pandasとSparkのDataFrameを両方サポート**しています
- 入力データについて言うと、通常はCSVやJSONを読んでDataFrameにする場合、pandasかSparkかでコードの書き方は違いますよね。PixieDustは両者の違いを**sampleData(URL)**で隠蔽してくれます

- 同様にチャートや地図を用いた可視化を行う際もmatplotlib/Bokehなど著名なライブラリーの書き方は微妙に違いますが、PixieDustでは**display(df)**だけです。ウイジェットが起動したらあとは対話式に描画エンジンを切り替えることができますので、色々な**ライブラリーの文法を知らなくてもOK**＝エンドユーザー様でも分析が行えます。


# 分析対象データの作り方(Load Data)について、もうすこし細かく

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/03e49ee0-d778-eb62-0167-b68696470ca9.png)

- (1)のsampleData()というAPIを使うと楽ですが、必須ではありません。(2)のように自分で好きな方法でpandasかSparkのDataFrameを組み立て、それをdisplay(df)に渡すこともできます。sampleData()とdisplay()を**ペアで必ず使う必要があるわけではありません**
- (1) sampleData(URL)は引数のURLでファイルの所在を指定します
    - http://～/hoge.csvやfile://～/hoge.json等
    - ファイルはCSVとJSONをサポート
    - ファイルが圧縮されzip/gzの拡張子の場合は自動的に解凍
    - ZIPで複数ファイルの場合は先頭のファイルを利用
- sampleData()の出力のDataFrameがpandasのDataFrameになるか、SparkのDataFrameになるかはNotebook環境のSpark有無で決まります。pysparkで起動した場合などSpark環境下の場合はDataFrameもSparkになります。(引数でforcePandas=Trueを指定すれば強制的にpandasのDataFrameにできます）
    - 例:  `dataframe = pixiedust.sampleData(data_url, forcePandas=True)`


:triangular_flag_on_post: ここまでの説明でご推察のとおり、PixieDust自身はレンダリング(描画）エンジンを持っていません。グラフやチャートの描画自体はmatplotlibやbokehなどのライブラリーに「ヨロシク！」ってことで委任しています。データの読み込みについても同様。要は**PixieDustは様々な著名オープンソースの違いを隠蔽し、誰でも簡単に使えるようにしてくれる「便利なブローカー」**だとご理解いただくのがいいと思います。


# やってみる
以下、インストールと基本的な操作を流してみましょう。

## 前提環境
以下をインストールしてある環境。最近流行ってる Jupyter Notebook/Pythonでデータ分析するなら普通の環境ですので説明は割愛します(condaで楽勝かと)
 
- Jupyter Notebook
- Python(2.7 or  3.5)
- Pandas **and/or** Spark 
- (必須) matplotlib / (オプション) Bokeh/Seaborn/Brunel

:triangular_flag_on_post: 前提は「全部を導入せねばならない」わけではありません。扱うデータがPandasだけで足りるならSparkは不要ですし、グラフ・チャートのレンダラーもmatplotlibさえあれば残りはオプション(無ければメニューで選べないだけ）です。

## インストール

ドキュメント 「[Install PixieDust](https://pixiedust.github.io/pixiedust/install.html)」に書いてありますが[^1]、要は`pip install pixiedust`でインストールするだけ、でいいと思います。(特にSparkなし=Jupyter/Python/Pandasの典型的なパターンなら）

```bash:ubuntu16.04の例
(py36) root@ubuntu:~# pip install pixiedust
Collecting pixiedust
  Downloading https://files.pythonhosted.org/packages/a8/d1/e3df504005abd892fc5ddfabcb23f5d1fc4d74290f0efe4767e23293d9f5/pixiedust-1.1.11.tar.gz (190kB)
    100% |████████████████████████████████| 194kB 959kB/s
Collecting mpld3 (from pixiedust)
  Downloading https://files.pythonhosted.org/packages/91/95/a52d3a83d0a29ba0d6898f6727e9858fe7a43f6c2ce81a5fe7e05f0f4912/mpld3-0.3.tar.gz (788kB)
    100% |████████████████████████████████| 798kB 302kB/s
<<途中省略>>
  Running setup.py bdist_wheel for mpld3 ... done
  Stored in directory: /root/.cache/pip/wheels/c0/47/fb/8a64f89aecfe0059830479308ad42d62e898a3e3cefdf6ba28
Successfully built pixiedust mpld3
Installing collected packages: mpld3, lxml, geojson, astunparse, markdown, colour, pixiedust
Successfully installed astunparse-1.5.0 colour-0.1.5 geojson-2.4.0 lxml-4.2.4 markdown-2.6.11 mpld3-0.3 pixiedust-1.1.11
(py36) root@ubuntu:~#
```

[^1]: [ドキュメント](https://pixiedust.github.io/pixiedust/install.html)にはmac前提とかJava入れろとかJupyter_Kernel入れろとか書いてあるんですが、ubuntu16.04ではやらなくても特に問題なし、でした。ネタ本「[Thoughtful_DataScience](https://www.packtpub.com/big-data-and-business-intelligence/thoughtful-data-science)」にも特に書いてなかったです。Java入れろとか、Spark/Scalaを意識したもの?

## データのロード

:blue_book: ドキュメント：[Load Data](https://pixiedust.github.io/pixiedust/loaddata.html)

Jupyterを起動して以下を実行します

```py
import pixiedust
df = pixiedust.sampleData()
```
引数なしのsampleData()ではサンプルデータの一覧が表示されます

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/637ba9c7-ef4b-aa57-31c0-cda7c0e104e6.png)

6番目の住宅価格(Million dollar home sales in Massachusetts, USA Feb 2017 through Jan 2018)のデータを使いましょう。引数に6を設定します。

```py
df = pixiedust.sampleData(6)
```

データがダウンロードされ、PandasのDataFrameになります
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/4486b9d1-edd2-42f2-6abb-1260021b77a7.png)
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/807f21a2-19c4-d804-c001-fe7903849031.png)

:triangular_flag_on_post: 上記はサンプルデータを使いましたが、実際はURLにファイルの所在を書きます。以下のような感じです。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/4a611750-3929-0acf-cffb-c68b36cf9345.png)

## データの表示
:blue_book: ドキュメント：[Display Data](https://pixiedust.github.io/pixiedust/displayapi.html)

display(df)でPandasのDataFrameを渡すとウイジェットが表示されます。

```py
display(df)
```

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/5c22c28e-ab45-be39-7711-0bcb70c66bff.png)

| # | 説明 |
|:---|:---|
| 1 | 表形式でデータフレームを表示します|
| 2 | チャートの種類を選択します |
| 3 | データをエクスポートします |
| 4 | データをフィルターで絞り込みます |
| 5 | X軸・Y軸、件数などの設定 |
| 6 | PixieAppとしてセルの内容をWeb公開/シェアします |
| 7 | データのスキーマ |
| 8 | データの表示領域 |
| 9 | 表示に即したサブメニュー |

(2) チャートの種類 
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/f4f5118c-86f6-442c-72d8-4021d872e506.png)
(3) データのエクスポート
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/08cb52ac-12ab-64d6-cd57-141676700009.png)
(4) データをフィルタ～表示対象データを絞込み/統計値も見られます
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/03c3b2b3-4e08-5da4-abd8-abddc04b8237.png)
(5) オプションの指定
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/ea924223-2304-1c4a-203c-ebcb41d6eed0.png)

## グラフ
「Scatter Plot」を選び、「オプション」で上記のようにX軸=SQUARE FEET（広さ) Y軸=PRICE(価格)を設定します。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/6f97c3d5-681a-3c99-beae-a2b06adac506.png)

matplotlibのチャートが表示されました。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/cc4774e9-fa24-1831-0f79-77d8513299f0.png)

レンダラーをbokehに切り替えると、点の色やチャートの移動・拡大・縮小などができるようになります。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/df18c7d6-6e69-e7ed-ded7-5c3380ecf543.png)

レンダラーをseabornに切り替えると、kindで色々な表示形式を選べます。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/aeefd827-5c6c-f47c-d3cf-9b664e9c93a1.png)

:triangular_flag_on_post: matplotlib以外のレンダラーはオプションです。導入されていなければメニューに表示されません。

チャートやデータを変えて、色々触ってみてください。

## マップ
次はマップを見ます。マップはチャートと違って、MapboxとGoogle Mapsでは**できることが異なります**。
 
- GoogleMapsでは国名、都市名などのデータを軸に設定した[GeoChart](https://developers.google.com/chart/interactive/docs/gallery/geochart)を作れます。(がそれ以外のマップやチャートは作れません）
- MapBoxでは緯度/経度データを用いて細かい地図情報を操作できます

#### Google MapsのGeoChart
すいません、API Keyがうまく認識されないので「こんなの」という絵だけ貼って終わりにします。「オプション」で地名や国名をX軸に設定します。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/6076adb5-48c1-3d27-8438-bcd207455107.png)


#### MapBox
チャートの種類からMapを選び、「オプション」のX軸に緯度/経度(Latitube/Longitude)を選定します。MapboxのAccess Tokenは今はデフォルトで設定されているものでもかまいません。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/70cda609-6765-fb52-bc6b-fbc67745c9b6.png)

右側のペインで見映えや縮尺を変更できます。
![mapbox-05.gif](https://qiita-image-store.s3.amazonaws.com/0/108535/660c7010-5ff5-94bf-8999-dca23cb2edff.gif)

:newspaper: ブログ「 [Mapping for Data Science with PixieDust and Mapbox](https://medium.com/ibm-watson-data-lab/mapping-for-data-science-with-pixiedust-and-mapbox-b5aa1d9532b9)」に紹介あります。

以上、２－３行で簡単にインタラクティブなチャートウィジェットがつくれました。あとはあれこれ触ってみてください。「これだけで探索的データ分析(EDA)ができる！」とまでは申しませんが、チャートの描画がすごく楽なので、pandasの本体の機能や[pandas_profiling](https://qiita.com/h_kobayashi1125/items/02039e57a656abe8c48f)などど併用すればいいのかなと思います。

# Tips
## チャートの設定を毎回一からやるの面倒..

Pixiedustではチャートの設定はJupyter Notebookのセルのメタデータとして保管していますので、再起動してもチャートは残っています。セルを再実行すれば描画は再現されます。(毎回一から設定し直し、というわけではありません）

とはいえ別のシートやセルに設定をコピーしたい場合もあるかと思います。その場合は以下の手順で設定をメタデータとして表示・編集できます。（別途ご紹介予定のPixieAppsではメタデータを使います）

Jupyter Notebookメニューの「View」-「Cell Toolbar」-「**Edit Metadata**」
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/75af8c71-08ed-b588-b565-1ee64d9af137.png)

すると各セルの右上にボタンが表示されます
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/87c24e3c-276e-25e9-95bd-a300ab134366.png)

ボタンを押すと現在の設定がjsonで保存されているのが見られます
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/3c6cd7cc-f139-7b76-e670-7eb7009cf028.png)

このテキストを別のセルのメタデータにコピペするとチャートが再現します

## ログ

たまにエラーで描画が失敗したりするケースがあります。その場合は以下のセルマジックでログを表示できます。問題判別に便利です。

`%pixiedustLog -l debug`

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/ed872b9b-2012-5a10-1b47-b629d6c4fdf2.png)

パラメータは下記
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/01b7acff-d730-b00a-89f8-2be510805148.png)

以上です。PixieDustは実はウィジェット以外にも豊富な機能を持ったライブラリーです。その全容を知りたい方は記事「[Jupyter/Pythonでデータ分析する人にお勧めしたい！便利なライブラリー 「PixieDust」をザクッと紹介します](https://qiita.com/ishida330/items/53f1b0df2247fab5c6dd)」もご参照ください。