【Python】 可視化ライブラリAltairの便利な使い方

Altair

Pythonの可視化ライブラリAltairはMatplotlibなどの他のライブラリを普段使っていると、コードの書き方が独特に感じてとっつきにくい印象があります。しかし一度慣れてしまうとグラフを作成する過程でデータの集計を指定できたり、インタラクティブなグラフを簡単に描けるので非常に便利です。またMatplotlibだと軸を丁寧に指定したり他のツールをインストールしないと、文字が細かすぎて見えなかったり、日本語が文字化けしたりしますが、Altairではそのあたりの調整を”いい感じ”で対処してくれる印象があります。今回はAltairの基本的な使い方と便利な応用方法をまとめました。

ライブラリのインストール

Altairと使用例に使うデータセットを読み込むためのVega datasetsをpipもしくはcondaでインストールします。

pip install altair vega_datasets
conda install -c conda-forge altair vega_datasets

AltairとVega datasetsをインポートします。また今回はVega datasetsの中のcarsデータセットを使います。

import altair as alt
from vega_datasets import data

source = data.cars()

carsは以下のように自動車の車名、燃費(Miles_per_Gallon)や馬力(Horsepower)等が格納されたデータセットです。

基本的な使用方法

最初にalt.Chartの中に使用するPandas Dataframeを指定し、その後にグラフの種類を指定します。次の例では散布図を表すmark_circleを指定していますが、以下のように様々な種類を指定できます。

  • 散布図:mark_circle
  • 棒グラフ:mark_bar
  • 折れ線グラフ:mark_line

Example Galleryで色々なグラフの作り方が紹介されています。

encodeの中で、x軸とy軸のデータを指定し、データの属性毎に色を分けたければcolerで属性データを指定します。ここではx軸にDisplacement(排出量)、y軸にMiles_per_Gallon(燃費)を指定し、colorをOrigin(地域)にしています。propertiesのwidthとheightでグラフの縦横の大きさを指定できます。

alt.Chart(source).mark_circle(size=50).encode(
    x='Displacement',
    y='Miles_per_Gallon',
    color='Origin'
).properties(
    width=400, height=300)

上記のコードを実行すると下図が作成されます。ここまでが基本的な使い方です。

集計した結果をプロット

グループ毎の集計

次にOrigin(地域)毎のHorsepowerの平均値を棒グラフでプロットします。Dataframeのgroupbyで集計した後に上記の基本操作に従って作図をしても良いのですが、ここではAltairのtransform_aggregateを使用します。transform_aggregateの中で平均値を格納する新しい変数avg_hpを定義してそこに’mean(Horsepower):Q’と指定し、groupbyでOrigin列を指定します。このようにするだけでHorsepower列の地域毎の平均値を集計した棒グラフを作成できます。meanをmedian, max等に変えると中央値や最大値を出力することもできます。

alt.Chart(source).mark_bar().encode(
    x=alt.X('Origin:N', title='地域'),
    y=alt.Y('avg_hp:Q', title='平均馬力')
).transform_aggregate(
   avg_hp='mean(Horsepower):Q', groupby=['Origin']
).properties(
    width=400, height=300, title='地域別平均馬力')

ここで ‘mean(Horsepower):Q’ のQは連続型の定量データを表しています。使用するDataframeで指定した型がそのままAltairで認識されますが、新しく定義したデータなどAltair側で型を認識できない場合はエラーが出たり、自動的に下表のQやNが指定される場合があります。意図したグラフがうまく作成できない時は、下表を基にデータ型を指定します。

また上記のコードではx軸、y軸のラベルをそれぞれ地域、平均馬力と指定しています。ラベルを指定する場合はalt.X、alt.Yの中でtitleを指定します(第1引数は列名です)。グラフのタイトルを指定する場合はpropertiesの中のtitleで指定します。 上記のコードを実行すると下図が作成されます。

時系列データの集計

次に日次の時系列データを月別に集計してグラフを作成します。Year列にyyyy-mm-ddの形で日付データが入っていますが、x軸を’yearmonth(Year):T’とすることで月次の日付に変換します(上表の通りTは日付の型を表します)。そしてy軸を’mean(Miles_per_Gallon):Q’とすることで、月毎の燃費の平均値が集計されます。

alt.Chart(source).mark_line(
).encode(
    x=alt.X('yearmonth(Year):T', title='日付'),
    y=alt.Y('mean(Miles_per_Gallon):Q', title='平均燃費'),
    color=alt.Color('Origin:N', title='地域')
).properties(
    width=400, height=300, title='平均燃費推移')

上記のコードを実行すると下図が作成されます。

x軸を ‘year(Year):T’とすると年別平均値の時系列プロットになり、’month(Year):T’とすると1月から12月までの平均値が集計されたグラフを作成できます。

インタラクティブなプロット

次にグラフを作成した後にインタラクティブに操作できるように設定します。

selection

ここでは最初に作成した散布図にインタラクティブな機能を追加します。まずはシンプルに、グラフを作成した後に何らかの操作で選択したグループにだけ色が付くように設定します。次のコードでは凡例に示されたグループ名をクリックすると、そのグループだけ色が残り、その他のグループは色が無くなってlightgreyになるように設定しています。alt.selection_multiで凡例に使うグループを指定し、alt.conditionでどのように色が変更されるかを指定した上で、それぞれselection, colorに格納します。
それらをencodeと新たに設定するadd_selectionに追加します。

selection = alt.selection_multi(fields=['Origin'], bind='legend')
color = alt.condition(selection,
                      alt.Color('Origin:N', title='地域'),
                      alt.value('lightgray'))

alt.Chart(source).mark_circle(size=50).encode(
    x=alt.X('Displacement:Q', title='排出量'),
    y=alt.Y('Miles_per_Gallon:Q', title='燃費'),
    color=color
).properties(
    width=400, height=300
).add_selection(selection)

上記のコードを実行するとまずは下図が作成されます。

グラフが作成された後に、凡例のJapan付近をクリックすると日本のデータだけ色が残って他の地域のデータはlightgreyになります。尚、shift+クリックで複数のグループを選択することもできます。

brush

次にマウスで選択した範囲のデータにインタラクティブな操作を加えるbrushという機能を追加します。ここでは複数のグラフを作成します。1つは上の例と同じ散布図、もう1つは地域毎のデータ数を棒グラフにしたものです。散布図はマウスで選択した範囲にだけ色を残し、棒グラフは散布図で選択した範囲のデータ数に変化するように設定します。

インタラクティブな操作にbrushを使う場合はselection_intervalを指定します。colorは選択されたグループ以外はlightgreyにするので先ほどの例と同じです。散布図のコードは先ほどと同じでencodeとadd_selectionにそれぞれ、colorとbrushを追加します。棒グラフは散布図で選択された範囲にフィルタリングした上でデータ数を選択するためにtransform_filterにbrushを追加します。またここでは2つのグラフに共通するグラフの特徴をbaseに格納して、それを散布図のpointsと棒グラフのbarsで使用しています。複数のグラフを横に並べる場合はhconcatを使います(縦に並べる場合はvconcatです)。

brush = alt.selection_interval()
color = alt.condition(brush,
                      alt.Color('Origin:N', title='地域'),
                      alt.value('lightgray'))

base = alt.Chart(source).properties(width=300, height=300)
points = base.mark_circle(size=50).encode(
    x=alt.X('Displacement:Q', title='排出量'),
    y=alt.Y('Miles_per_Gallon:Q', title='燃費'),
    color=color
).add_selection(
    brush
)
bars = base.mark_bar().encode(
    x=alt.X('count(Origin):Q', title='レコード数'),
    y=alt.Y('Origin:N', title=''),
    color=alt.Color('Origin:N', title='地域')
).transform_filter(
    brush
)

alt.hconcat(points, bars)

上記のコードを実行するとまずは下図が作成されます。

次に散布図の燃費の35-45、排出量の50-300周辺をマウスで選択します。すると、散布図では選択した範囲だけ色が残り、棒グラフは散布図で選択された範囲に含まれるデータ数に変更されます。

以上で、インタラクティブな機能を追加することができました。

Altairはコードの書き方が独特ですが、一度ルールに慣れると非常に直感的に様々なグラフをきれいに描けるので、他の便利な使い方も調べて今後も使っていきたいライブラリです。

AltairとStreamlitを組み合わせてダッシュボードを作成する方法はこちらです。

コメント

タイトルとURLをコピーしました