Altairのすすめ！Pythonによるデータの可視化

## この記事について
Pythonのデータ可視化ライブラリー、**Altair**の紹介です。日本語の情報が少ないので布教用に記事にします。英語に抵抗がない方は[公式ページ](https://altair-viz.github.io/index.html)を見るのが一番わかりやすいと思います。

## インストール
`pip`コマンドで簡単にインストールできます。`vega_datasets`はこの後使うので一緒にインストールしましょう。

```shell
pip install altair vega_datasets
```
私はGoogle Colaboratoryを使いましたが、インストールなしで最初から使えました。

## 事前準備
以下でライブラリとデータセットを読み込んでください。

```Python
import altair as alt
from vega_datasets import data
iris = data.iris()
```
AltairはPandasとの連携が得意で、`iris`はPandasのDataFrameです。

## 基本的な可視化
以下はJupyterなどで直接可視化する想定のコードです。htmlで出力したい場合は末尾に`.save("filename.html")`を足してください。`.interactive()`はなくても大丈夫ですが、書くとグラフを動かせるようになります。**この記事に貼るのは普通の画像なので、ぐりぐり動かしたい方は[こちら](https://colab.research.google.com/drive/1mx45IhxNSG2BquiCCAvdib5iN0tak27o#scrollTo=BoakIbn0wbg_)でどうぞ**。

### 例①散布図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540947/350ac7c6-b4de-dca0-e79d-45247eb86dfc.png)

x軸とy軸の値を以下のように指定します。コメントのような`alt.X()`という書き方もできて、複雑な可視化の際はこちらを使います。

```Python
alt.Chart(iris).mark_point().encode(
    x="sepalLength", # alt.X("sepalLength"),
    y="sepalWidth", # alt.Y("sepalWidth"),
    color="species"
).interactive()
```
### 例②棒グラフ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540947/ba1d7b7c-003e-3c74-8d9d-bdbf45bfa5c8.png)

`average()`で`species`ごとに平均をとっているのがポイントです。平均以外にも様々な操作ができて、一覧は[ここ](https://vega.github.io/vega-lite/docs/aggregate.html#ops)で確認できます。

```Python
alt.Chart(iris).mark_bar().encode(
    x="average(sepalLength)", # alt.X("sepalLength", aggregate="average"),
    y="species", # alt.Y("species"),
).interactive()
```
要領はこんな感じです。`make_xxxxx`の部分を`make_line`とすれば折れ線グラフなんかも簡単に書けます。困ったときは公式ページの[ギャラリー](https://altair-viz.github.io/gallery/index.html)から類似したグラフを探せば大体解決します。

## TIPS（加筆するかも）

### マウスオーバーで情報表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540947/d327b9b5-2958-22c8-d7c9-7f204954e33b.png)

`tooltip`引数で指定した情報がマウスオーバーで表示されます。

```Python
alt.Chart(iris).mark_point().encode(
    x="sepalLength",
    y="sepalWidth",
    color="species",
    tooltip=["sepalLength", "sepalWidth", "petalLength", "petalWidth", "species"]
).interactive()
```

### 軸を0から書きたくない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540947/02089d78-b95b-a800-81b9-c4d94313dd89.png)

量的なデータは基本的に0を含んで可視化されます。上のグラフは0を含まないよう`zero=False`で明示しています。

```Python
alt.Chart(iris).mark_point().encode(
    alt.X("sepalLength", scale=alt.Scale(zero=False)),
    alt.Y("sepalWidth", scale=alt.Scale(zero=False)),
    color="species"
).interactive()
```

### データ型の指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540947/9e37bbb4-5776-1bfd-d05d-2611035e2897.png)

名義尺度が整数になっていることはよくありますよね。そのときは`species_int:N`のように名義尺度であることを明示します。ちなみに順序尺度は`:O`、量的データなら`:Q`です。詳細は公式ドキュメントの[ここ](https://altair-viz.github.io/user_guide/encoding.html#encoding-data-types)に記載があります。

```Python
# 整数値に変換 (setosa: 0, versicolor: 1, virginica: 2)
iris["species_int"] = [["setosa", "versicolor", "virginica"].index(x) for x in iris["species"]]

# 正しい例
alt.Chart(iris).mark_point().encode(
    x="sepalLength",
    y="sepalWidth",
    color="species_int:N"
).interactive()
```
ちなみに`:N`を付けないと以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540947/4dd52618-d963-540f-d08f-75637b6eb74c.png)

### MaxRowError対応
5000行超えると怒られます。[ここ](https://altair-viz.github.io/user_guide/faq.html#maxrowserror-how-can-i-plot-large-datasets)の情報を参考に以下を実行。

```Python
alt.data_transformers.disable_max_rows()
```

## 最後に
シンプルに記述できて探索的な分析には便利です。欠点があるとすると、htmlの出力は簡単ですがpngの出力がやや大変そうでした。参考になれば！