乙Py先生のプログラミング教室
初学者のためのプログラミング学習サイト

Python.プログラミング

今回はインタラクティブな可視化が行えるライブラリ
Altairのご紹介です。


解説動画はこちら



Altairライブラリについて

少ないコードで複雑なビジュアライゼーションを作成できる
可視化ライブラリです。

静止画でなくインタラクティブな
ビジュアライゼーションを行うことができます。

Pandasデータフレームと相性が良く
ダッシュボード制作などで活用されるケースが増えています。



他の可視化ライブラリとの違い

スクリーンショット 2024-08-10 15.11.51

Altairの他にも沢山の可視化ライブラリがあります。

その中でもMatplolibは定番の可視化ライブラリですが
ドキュメントの数量は多く、全てを覚えるのはなかなか大変です。

AltairはPlotlyのようなインタラクティブな可視化が出来る事と
学習コストがかなり少ない事が大きな利点です。

可視化の目的によって
これらのライブラリを使い分けると良いでしょう。


Altairの使い方

1.ライブラリのインポート

Google ColabではそのままAltairを利用できます。
import pandas as pd
import numpy as np
import altair as alt
import warnings
warnings.filterwarnings('ignore', category=FutureWarning)

その他、必要なライブラリを読み込んでおきましょう。


2.データの用意

適当なデータをPandasデータフレームで作成しておきます。
# サンプルデータの作成
data = pd.DataFrame({
    'x': [1, 2, 3, 4, 5],
    'y': [2, 3, 4, 5, 6]
})

3.チャートの作成

Altairの基本的なチャートは、alt.Chartオブジェクトを使用して作成します。

mark_*メソッドでマーク(グラフの種類)を指定し
encodeメソッドでデータのエンコード(軸、色、大きさなど)を
指定する構文になっています。

チャート変数 = alt.Chart(データ変数).mark_point().encode(
  エンコード内容
)

# チャートの作成
chart = alt.Chart(data).mark_point().encode(
    x='x',
    y='y'
)

# チャートの表示(Jupyter Notebook環境などで)
chart
visualization (9)

指定できるmark_*メソッド例として

mark_point:ポイントマーク(散布図)
mark_line:折れ線グラフ
mark_bar:棒グラフ
mark_circle:バブルチャート
mark_rect:矩形マーク(ヒートマップなど)
mark_boxplot:箱ひげ図
mark_errorband:エラーバンド
mark_errorbar:エラーバー
mark_geoshape:地理シェープ(地図)
mark_image:画像マーク
mark_area:エリアチャート
mark_rule:ルールマーク(基準線など)
mark_square:四角形マーク(散布図の一種)
mark_text:テキストマーク
mark_tick:ティックマーク

こんな感じのグラフを作成できます。


4. エンコーディング

encodeメソッドを使用して
データを視覚的な属性にマッピング出来ます。

x : x軸
y : y軸
color : 色
size : サイズ
shape : 形
tooltip : ホバー時に表示されるツールチップ
data = pd.DataFrame({
    'x': [1, 2, 3, 4, 5],
    'y': [2, 3, 4, 5, 6],
    'category': ['A', 'B', 'A', 'B', 'A']
})

chart = alt.Chart(data).mark_point().encode(
    x='x',
    y='y',
    color='category',
    tooltip=['x', 'y', 'category']
)
chart

5.インタラクティブ性の追加

interactiveメソッドを使用して
グラフにインタラクティブ機能(ズーム、パンなど)を
追加できます。
chart = alt.Chart(data).mark_point().encode(
    x='x',
    y='y',
    color='category'
).interactive()
chart

6.レイヤリングと複合グラフ

Altairでは複数のチャートをレイヤリングして
重ね合わせることも可能です。

+演算子を使用してチャートを合成します。

points = alt.Chart(data).mark_point().encode(
    x='x',
    y='y',
    color='category'
)

lines = alt.Chart(data).mark_line().encode(
    x='x',
    y='y',
    color='category'
)

combined_chart = points + lines
combined_chart


Altairグラフのコードサンプル

散布図
# サンプルデータの作成
np.random.seed(42)
data = pd.DataFrame({
    'x': np.random.randn(100),
    'y': np.random.randn(100),
    'category': np.random.choice(['A', 'B', 'C'], 100)
})

# インタラクティブな散布図の作成
scatter_plot = alt.Chart(data).mark_point().encode(
    x='x',
    y='y',
    color='category',
    tooltip=['x', 'y', 'category']
).interactive()
scatter_plot
visualization (5)

棒グラフ
# サンプルデータの作成
data = pd.DataFrame({
    'category': ['A', 'B', 'C', 'D', 'E'],
    'value': [5, 3, 6, 7, 2]
})

# インタラクティブな棒グラフの作成
bar_chart = alt.Chart(data).mark_bar().encode(
    x='category',
    y='value',
    tooltip=['category', 'value']
).interactive()
bar_chart
visualization (4)

折れ線グラフ
# サンプルデータの作成
data = pd.DataFrame({
    'date': pd.date_range(start='2023-01-01', periods=100),
    'value': np.random.randn(100).cumsum()
})

# インタラクティブな折れ線グラフの作成
line_chart = alt.Chart(data).mark_line().encode(
    x='date:T',
    y='value:Q',
    tooltip=['date:T', 'value:Q']
).interactive()
line_chart
visualization

ヒートマップ
# サンプルデータの作成
data = pd.DataFrame({
    'x': np.repeat(np.arange(1, 11), 10),
    'y': np.tile(np.arange(1, 11), 10),
    'value': np.random.randn(100)
})

# インタラクティブなヒートマップの作成
heatmap = alt.Chart(data).mark_rect().encode(
    x='x:O',
    y='y:O',
    color='value:Q',
    tooltip=['x', 'y', 'value']
).interactive()
heatmap
visualization (2)

バブルチャート
# サンプルデータの作成
np.random.seed(42)
data = pd.DataFrame({
    'x': np.random.randn(100),
    'y': np.random.randn(100),
    'size': np.random.rand(100) * 100,
    'category': np.random.choice(['A', 'B', 'C'], 100)
})

# インタラクティブなバブルチャートの作成
bubble_chart = alt.Chart(data).mark_circle().encode(
    x='x',
    y='y',
    size='size',
    color='category',
    tooltip=['x', 'y', 'size', 'category']
).interactive()
bubble_chart
visualization (1)

ヒストグラム
# データの生成
np.random.seed(42)
data = pd.DataFrame({
    'value': np.random.normal(loc=0, scale=1, size=1000)
})

# ヒストグラムの作成
histogram = alt.Chart(data).mark_bar().encode(
    alt.X('value:Q', bin=True, title='Value'),
    alt.Y('count()', title='Frequency')
).interactive()
histogram
visualization (12)

箱ひげ図
# データの生成(例: 1000個のランダムな数値を3つのカテゴリに分ける)
np.random.seed(42)
data = pd.DataFrame({
    'category': np.random.choice(['A', 'B', 'C'], size=1000),
    'value': np.random.normal(loc=0, scale=1, size=1000)
})

# 箱ひげ図の作成
boxplot = alt.Chart(data).mark_boxplot().encode(
    x='category:O',
    y='value:Q'
).interactive()
boxplot
visualization (11)

エリアチャート
# データの生成
data = pd.DataFrame({
    'year': [2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007],
    'value': [10, 15, 13, 17, 20, 19, 15, 10]
})

# エリアチャートの作成
areachart = alt.Chart(data).mark_area().encode(
    x='year:O',
    y='value:Q'
).interactive()
areachart
visualization (10)




まとめ

Altairは可視化ライブラリの中でも比較的学習コストが低く
かなり使い勝手の良い可視化ライブラリです。

特にインタラクティブな可視化を行えるのが魅力的なライブラリで
最近はデータサイエンスやデータ分析の分野で広く採用されて来ています。

WEBアプリを作成できるStreamlitライブラリと相性が良く
簡易なアプリ作成やダッシュボード作成などにも向いています。

Matplotlibの可視化に物足りなくなって来たら
こちらのライブラリはオススメです。

それでは。





今回はPythonの実装を
めちゃくちゃ高速化出来るという
codonライブラリを試してみました


解説動画はこちら




このcodonライブラリですが
C/C++に匹敵する実行速度を実現出来るという
コンパイラです

Pythonのライブラリだと他にも

PyPy
Cpython
Numba 

などのコンパイル型
高速化ライブラリが存在しますが
それを超える速度を出せるとか・・・

一応の制約として
標準ライブラリ以外は
含める事ができない制約があるようです


高速化のベンチマークなどは
こちらにコードがあります

codon

今回はGoogle Colabで
検証してみたいと思います


Google Colab上へのインストール
%%bash
/bin/bash -c "$(curl -fsSL https://exaloop.io/install.sh)"

まずはライブラリをインストールしないと
動かないのでこれでコマンド等をインストールします

インストール後はcodonコマンドが使えます
実行の仕方
1.Pythonの実装ファイルを作成する「.py」
2.Google Colabのファイル置き場に置く
3.codonコマンドでコンパイルしながら実行
codon run ファイル名

これでコンパイルしながら実行されます

4.実行用のファイルをコンパイルする
codon build -release -exe ファイル名
コンパイルしたファイルの実行
./ファイル名

これらでPython実装からcodonで
実行が行えます




素数判定のプログラムで検証

まずは素数の判定に使われるプログラムで
時間を計測してみます

prime.pyというファイルにして
ファイルを配置します

# Pythonでの実装
from sys import argv
from time import time
def is_prime(n):
    factors = 0
    for i in range(2, n):
        if n % i == 0:
            factors += 1
    return factors == 0
limit = int(10000)
total = 0
t0 = time()
for i in range(2, limit):
    if is_prime(i):
        total += 1
t1 = time()
print(total)
print(t1 - t0)
1229
2.6382787227630615

Pythonでの実装は2.63秒ほどでした

codonでコンパイルしながら実行します
!/root/.codon/bin/codon run /content/prime.py
1229
0.112064

20倍ほどは早くなっていますね





アッカーマン関数での比較

次はアッカーマン関数で比較です
この関数は非負整数 m と n で
定義される関数のことで

与える数が大きくなると
爆発的に計算量が大きくなり
性能測定などに用いられるようです

このプログラムを使用しました
再帰を伴うので、上限を開放しておかないと
動かない様です
# pythonによる実装
import time
import sys

#再帰回数の上限を開放
sys.setrecursionlimit(100000)

def ackermann(m: int, n: int) -> int:
    if m == 0:
        return n + 1
    elif n == 0:
        return ackermann(m - 1, 1)
    else:
        return ackermann(m - 1, ackermann(m, n - 1))

m, n = 3, 10
start = time.time()
result = ackermann(m, n)
end = time.time()
print(f"ackermann({m}, {n}) = {result}")
print(f"elapsed time: {int((end - start) * 1000)} [ms]")
ackermann(3, 10) = 8189
elapsed time: 7522 [ms]


codon版は再帰の回数を少し増やしています
!/root/.codon/bin/codon run /content/coden.py
ackermann(3, 11) = 16381
elapsed time: 847 [ms]


最適化してコンパイルしておいたものを
実行してみると

!/root/.codon/bin/codon build -release -exe /content/coden.py
!/content/coden
ackermann(3, 11) = 16381
elapsed time: 185 [ms]

同じ回数ではないですが
再帰回数が2倍に増えていても
実行時間は50倍ほどは速そうです


ベンチマークによると
100倍ほど早くなるそうで
簡単なアルゴリズムなんだけど
実行回数が多いとか
時間がかかる部分を大幅に短縮出来ますね

pure python が輝ける日が来るかもしれません

今回はPython実装を高速化させる
codon について紹介しました

今回はここまでです
それでは


このページのトップヘ