Altair

Altairは,Pythonでインタラクティブ・プロットを簡単に作れるライブラリの一つ。以下は折れ線グラフの作り方の説明。

まずは基本モジュール読み込み。

import pandas as pd
import datetime
import warnings
warnings.filterwarnings('ignore')

読み込むデータ形式

データは以下のデータサンプルのようなlong formatにする。

情報源

from vega_datasets import data

source = data.stocks()
display(source.head())
symbol date price
0 MSFT 2000-01-01 39.81
1 MSFT 2000-02-01 36.35
2 MSFT 2000-03-01 43.22
3 MSFT 2000-04-01 28.37
4 MSFT 2000-05-01 25.45

500行未満のデータの場合

import altair as alt

alt.Chart(source).mark_line().encode(
    x="date",
    y="price",
    color="symbol"
).properties(
    height=300, width=500
)

インタラクティブ・プロットにする

凡例(legend)のクリックで表示曲線の選択

凡例をクリックすることで,見たい折線を太く表示することが出来る。

情報源

selection = alt.selection_multi(fields=["symbol"], bind="legend")

alt.Chart(source).mark_line().encode(
    x="date",
    y="price",
    color="symbol",
    opacity=alt.condition(selection, alt.value(1), alt.value(0.1))
).properties(
    height=240, width=400
).add_selection(
    selection
)

マウスカーソルに近い折れ線を選択

# カーソルによる情報抽出条件設定(近傍点からその属性(symbol)情報抽出)
hover = alt.selection(
    type="single", on="mouseover", fields=["symbol"], nearest=True
)

# ここは基本通り
line = alt.Chart(source).mark_line().encode(
    x="date",
    y="price",
    color="symbol",
).properties(
    height=240, width=400
)

# カーソルに近い点のsymbol情報を抽出
point = line.mark_point().encode(  # データ点を描く
    opacity=alt.value(0)  # データ点は透明にする
).add_selection(hover)  # カーソルに近いデータ点を検出し,そのクラス(fields)を判定

# カーソルによる検出情報(hover)に応じた,線の太さの調節
singleline = lineplot.mark_line().encode(
    size=alt.condition(~hover, alt.value(1), alt.value(3))
)

point + singleline

座標情報の表示

カーソルのx座標に対する,各折線の座標値を表示する

情報源

# カーソルによる情報抽出条件設定(近傍点から横軸(date)情報抽出)
nearest = alt.selection(
    type="single", on="mouseover", fields=["date"], nearest=True, empty='none'
)


# ここは基本通り
line = alt.Chart(source).mark_line().encode(
    x="date",
    y="price",
    color="symbol",
).properties(
    height=300, width=500
)

# カーソルのx座標取得
selectors = line.mark_point().encode(  # データ点を◯で描く
    opacity=alt.value(0)  # データ点は透明にする
).add_selection(nearest)  # カーソルに近いデータ点を検出し,x座標値(date)を判定

# カーソルの近くの点をハイライト
points = line.mark_point().encode(
    opacity=alt.condition(nearest, alt.value(1), alt.value(0))
)

# 情報表示
text = line.mark_text(align='left', dx=5, dy=-5).encode(
    text=alt.condition(nearest, 'price', alt.value(' '))
)

# カーソル位置に縦線を描く
rules = alt.Chart(source).mark_rule(color='gray').encode(
    x='date',
).transform_filter(
    nearest
)

# まとめて表示
alt.layer(
    line, selectors, points, rules, text
).properties(
    height=240, width=400
)

500行以上のデータの場合

データが500行以上あるときには,グラフ描画のためのデータが巨大になる。特にjupyter形式のnotebookに保存する場合は,グラフ情報でファイルサイズが大きくなるので,以下のように外部ファイルを作ってプロットする。 このとき,読み込みデータの型を指定する必要あり。

T: temporal (日時)
Q: quantitative (数値)
N: nominal (文字)

情報源

url = 'sample.json'
source.to_json(url, orient='records')

alt.Chart(url).mark_line().encode(
    x="date:T",
    y="price:Q",
    color="symbol:N"
).properties(
    height=240, width=400
)

jupyter と altair と hugo

jupyter 上で altairのグラフを作り,md形式でファイルで出力してhugoでhtml化すると,もれなくhtml上でもグラフを見れる。素晴らしい。ただし,グラフ用データが全てファイル内に記載されるので,下手をするとえらく大きなhtmlファイルを作ることになるので注意。 そこで以下のように自動化した。