こんにちは、JS2IIUです。HoloViewsは最近知ったのですが、みやすいグラフを生成してくれる素晴らしいツールです。これまでmatplotlibで作っていたグラフのいくつかはHoloViewsで作り直してみたいと思っています。このHoloViewsをPanelと組み併せてみます。
はじめに
データ可視化は、データの分析や理解において非常に重要な役割を果たします。HoloViewsは、Pythonで簡単にインタラクティブなプロットを作成できる強力なライブラリです。HoloViewsをPanelと組み合わせることで、動的かつインタラクティブなダッシュボードを構築できます。本記事では、基本的なHoloViewsの使い方から始め、Panelとの統合、動的なプロット、リアルタイムデータの可視化までを順に解説します。
HoloViewsの基本: インストールとシンプルなプロット
HoloViewsを使うには、まずライブラリをインストールする必要があります。以下のコマンドを実行してインストールしてください。
pip install holoviews
次に、簡単な折れ線グラフを作成してみましょう。
import holoviews as hv
import panel as pn
pn.extension('holoviews')
# データの定義
data = [(1, 2), (2, 3), (3, 5), (4, 7), (5, 11)]
# HoloViewsによる折れ線グラフの作成
curve = hv.Curve(data, 'X', 'Y')
# Panelによる表示
pn.pane.HoloViews(curve).show()
holoviews as hvでHoloViewsをインポートし、pn.extension('holoviews')でPanelにHoloViewsの拡張機能を追加します。hv.Curve()を使って、簡単な折れ線グラフを作成しています。dataには、(X, Y)の形式でデータポイントを定義します。- 最後に、
pn.pane.HoloViews()を使ってPanelにプロットを埋め込み、show()で表示します。
このコードを実行すると、X軸が1から5、Y軸が2から11までのデータを持つインタラクティブな折れ線グラフが表示されます。
グラフの横側にはZoomやSave機能のボタンが表示されています。わかりやすくて便利そうです。
複数のプロットを統合する
HoloViewsでは、複数の異なるプロットを統合して、複雑なビジュアライゼーションを作成することが可能です。次に、折れ線グラフと散布図を一緒に表示してみます。
import holoviews as hv
import panel as pn
import numpy as np
# データの定義
data = [(1, 2), (2, 3), (3, 5), (4, 7), (5, 11)]
# 新しいデータの定義
scatter_data = np.random.randn(100, 2) # 100点のランダムなX, Yデータ
# 折れ線グラフと散布図を作成
curve = hv.Curve(data, 'X', 'Y')
scatter = hv.Scatter(scatter_data, 'X', 'Y')
# 両方のプロットをオーバーレイ
overlay = curve * scatter
# Panelで表示
pn.pane.HoloViews(overlay).show()
hv.Scatter()を使って散布図を作成しています。scatter_dataは100点のランダムなデータであり、X軸とY軸のデータを持っています。curve * scatterとすることで、折れ線グラフと散布図を重ねて表示します。HoloViewsでは、このようにシンプルな演算でプロットをオーバーレイできます。
これにより、折れ線グラフと散布図が1つの図に重ねられて表示されます。
オーバーレイをするのに*(掛け算)で良いのはとても面白い仕様です。
動的なデータ可視化
HoloViewsとPanelを使うことで、動的に変化するデータを可視化することも簡単です。例えば、スライダーを使ってグラフのデータを動的に更新してみましょう。
import holoviews as hv
import panel as pn
import numpy as np
import bokeh
# HoloViewsでBokehをバックエンドとして使用
hv.extension('bokeh')
# 必要な拡張機能を読み込む
pn.extension()
# データの生成関数
def sine_wave(phase):
x = np.linspace(0, 10, 100)
y = np.sin(x + phase)
return hv.Curve((x, y), 'X', 'Y')
# スライダーの作成
slider = pn.widgets.FloatSlider(name='Phase', start=0, end=np.pi*2, step=0.1)
# 動的なプロットの作成
def update_curve(phase):
return sine_wave(phase)
# Panelでレイアウトを表示
layout = pn.Column(slider, pn.bind(update_curve, slider))
layout.show()
sine_wave()関数では、X軸に0から10の範囲、Y軸にフェーズを加えたサイン波のデータを生成します。pn.widgets.FloatSliderは、ユーザーが値を動的に変更できるスライダーウィジェットです。このスライダーを使ってサイン波のフェーズを変えます。@pn.depends()デコレータを使うことで、スライダーの値が変更されたときに自動的にプロットが更新されるようになります。
スライダーを動かすと、サイン波がリアルタイムで更新されるのを確認できるでしょう。さらに詳しい解説文を補足として、本記事の最後に載せていますので、ご興味ある方は併せてご覧ください。
リアルタイムデータの可視化
PanelとHoloViewsを組み合わせれば、リアルタイムデータの可視化も可能です。例えば、株価データやIoTデバイスのデータなどをリアルタイムで表示するダッシュボードを構築できます。次の例では、ランダムデータをリアルタイムに更新して表示します。
import time
import numpy as np
import holoviews as hv
import panel as pn
pn.extension('holoviews')
# 初期データの生成
x = np.linspace(0, 10, 100)
y = np.random.randn(100)
# HoloViewsの曲線を作成
curve = hv.Curve((x, y))
# Panelの動的コンポーネントとして定義
pane = pn.pane.HoloViews(curve, sizing_mode='stretch_width')
# データの更新関数
def update():
global y
y = np.random.randn(100)
curve.data = (x, y)
pane.object = curve
# 定期的にデータを更新
def stream_data():
while True:
time.sleep(1)
update()
# Panelレイアウトの表示
pn.state.add_periodic_callback(update, 1000)
pane.show()
pane = pn.pane.HoloViews()で、HoloViewsのグラフをPanelのコンポーネントとして定義します。update()関数では、新しいランダムなデータを生成し、それをcurveに設定します。pane.objectを更新することで、グラフがリアルタイムで更新されます。pn.state.add_periodic_callback()を使って、1秒ごとにupdate()関数が呼び出され、データがリアルタイムで更新されるようにしています。
このコードを実行すると、1秒ごとにランダムなデータで更新されるグラフがリアルタイムに表示されます。
まとめ
HoloViewsを使うと、少ないコードで強力なインタラクティブなデータ可視化が可能になります。Panelとの統合により、動的なプロットやリアルタイムデータの表示も簡単に実現できます。今回紹介した手法を使って、データ分析や監視ダッシュボードなど、さまざまな応用が可能です。
次回は、Panelアプリケーションの展開方法について解説します。お楽しみに!
補足:動的なデータ可視化サンプルの詳細説明
モジュールのインポート
import holoviews as hv
import panel as pn
import numpy as np
import bokeh
この部分では、必要なライブラリをインポートしています。
holoviews(hv): 高レベルなデータ可視化ライブラリで、宣言的にデータのプロットを行うことができます。ここでは、曲線プロットを生成します。panel(pn): Webアプリケーションを作成するためのライブラリで、ダッシュボードやインタラクティブなUIを簡単に作成できます。numpy(np): 数値計算ライブラリで、ここではサイン波のデータを生成するために使用します。bokeh:holoviewsが依存する描画バックエンドの一つ。holoviewsのプロットをブラウザに表示するために使用します。
HoloViewsでBokehバックエンドの設定
hv.extension('bokeh')
この行で、holoviewsが描画を行う際に使用するバックエンドをbokehに設定しています。holoviewsは複数のバックエンドに対応しており、bokehを指定することで、インタラクティブで高品質なWebベースのプロットが可能になります。
Panel拡張機能の読み込み
pn.extension()
pn.extension()は、panelで必要なフロントエンド(HTMLやJavaScriptのリソースなど)をロードするための命令です。このコマンドにより、作成するアプリケーションがブラウザで正しく動作するように設定されます。
データ生成関数
def sine_wave(phase):
x = np.linspace(0, 10, 100)
y = np.sin(x + phase)
return hv.Curve((x, y), 'X', 'Y')
sine_wave関数: この関数は、サイン波を生成してholoviewsのCurveオブジェクトとして返します。x = np.linspace(0, 10, 100): 0から10までの範囲を100分割して、等間隔のデータ点を生成します。y = np.sin(x + phase):xに対して、与えられた位相シフト(phase)を加えたサイン波を計算します。hv.Curve((x, y), 'X', 'Y'):holoviewsのCurveオブジェクトを作成し、x軸とy軸にデータをプロットします。
この関数は、与えられた位相シフトに基づいたサイン波のプロットを返す動的な可視化を提供します。
スライダーの作成
slider = pn.widgets.FloatSlider(name='Phase', start=0, end=np.pi*2, step=0.1)
slider:panelのウィジェットであるFloatSliderを使って、0から2πまでの範囲で動かせるスライダーを作成しています。name='Phase': スライダーのラベルを「Phase(位相)」としています。start=0, end=np.pi*2, step=0.1: スライダーの範囲は0から2πまでで、0.1刻みで値を調整できます。スライダーの値はサイン波の位相シフトとして使用されます。
動的なプロットの作成
def update_curve(phase):
return sine_wave(phase)
update_curve関数:pn.bindで呼び出され、スライダーの値を受け取り、その値に基づいて動的にsine_wave関数を呼び出して新しいプロットを返します。phase: スライダーの現在の値を受け取り、その値を基にしてsine_wave関数を呼び出します。
レイアウトの作成と表示
layout = pn.Column(slider, pn.bind(update_curve, slider))
layout.show()
pn.Column: レイアウトを垂直方向に並べるコンテナで、スライダーと動的なプロットを縦に配置しています。pn.Columnの中にスライダーと動的プロットを配置することで、UIのレイアウトが整えられます。slider: スライダーウィジェットをUIに配置します。pn.bind(update_curve, slider):pn.bindは、スライダーの値をupdate_curve関数にバインド(関連付け)し、スライダーを操作するたびにupdate_curveが呼び出されて動的にプロットが更新されます。
layout.show():layoutをブラウザで表示します。これにより、スライダーを動かすとサイン波の位相が変化する動的な可視化が可能になります。
全体の流れ
- データ生成:
sine_wave関数でサイン波のデータを生成します。 - UIの作成:
FloatSliderを使って位相を調整できるインタラクティブなUIを作成し、update_curveでスライダーの値に応じてプロットを更新します。 - レイアウトと表示: UIを
pn.Columnで整理し、layout.show()で表示します。
最後までご覧いただき有難うございました。73

