【Python】Dash入門編

Python
この記事は約18分で読めます。

こんにちは、JS2IIUです。Pythonで構築できるWebアプリケーションフレームワーク、Streamlit、Panelに続いて、Dash(https://dash.plotly.com)を紹介していきます。今回の入門編に続いて応用編も記事にしていく予定です。よろしくお願いします。

Dashとは?

Dashは、PythonでインタラクティブなWebアプリケーションを構築するための強力なフレームワークです。Flask、Plotly、React.jsを組み合わせて構築されており、主にデータ可視化やダッシュボード作成に使われます。Pythonでフルスタックのアプリケーションを作成でき、バックエンドやフロントエンドのコードがPythonのみで記述可能な点が特徴です。

こんなことできます、のギャラリーページは見応えがあります。

Dashの特徴

  • Pythonのみでの開発: HTMLやJavaScriptを直接記述せずに、すべてPythonでWebアプリケーションを構築可能。
  • インタラクティブなグラフ作成: Plotlyのパワフルなグラフライブラリを活用し、ダイナミックなグラフやデータのビジュアライゼーションを簡単に作成できる。
  • コールバック機能: UIの変化に応じてリアルタイムでデータが更新される双方向のやり取りが可能。
  • シンプルな構成: Flaskをベースにしているため、アプリの構造が非常にシンプルで、学習コストが低い。

メリット

  • 手軽なインタラクティブなアプリ作成: シンプルな構文で複雑なインタラクションを持つアプリを作成でき、データサイエンティストやエンジニアが容易に扱える。
  • 多彩なビジュアライゼーション: Plotlyを使った豊富なグラフを簡単に作成・カスタマイズ可能。
  • オープンソース: オープンソースであり、活発なコミュニティが存在するため、拡張性が高い。

デメリット

  • パフォーマンスの制約: 大規模なアプリケーションでは、パフォーマンスが低下することがある。
  • モバイル対応が弱い: デフォルトのスタイルがモバイルデバイスに最適化されていないため、追加のカスタマイズが必要な場合がある。
  • JavaScriptのカスタマイズが難しい: JavaScriptのコードを直接操作することがDashでは制限されるため、特殊なUI/UXを実現するには限界がある。

Dashの使い所

  • データダッシュボード: ビジネスインテリジェンスやデータ分析結果をインタラクティブに可視化したダッシュボードに適している。
  • リアルタイムデータ可視化: IoTや金融、気象データなどのリアルタイムデータの監視や分析に活用可能。
  • プロトタイピング: Webアプリケーションのプロトタイプ作成に最適で、素早くインタラクティブなデータ解析ツールを構築できる。

基本機能とサンプルプログラム

Dashの導入方法です。

dashと合わせてPandasも入れておくことをお勧めします。(と、本家ページに書いてありました)

pip install dash pandas

簡単なレイアウト作成

import dash
from dash import dcc, html
from dash.dependencies import Input, Output

app = dash.Dash(__name__)

app.layout = html.Div([
    html.H1("Dash基本アプリ"),
    dcc.Input(id='input-box', value='初期値', type='text'),
    html.Div(id='output-box')
])

@app.callback(
    Output('output-box', 'children'),
    [Input('input-box', 'value')]
)

def update_output(value):
    return f'入力された値: {value}'

if __name__ == '__main__':
    app.run_server(debug=True)

説明: このプログラムは、テキスト入力フィールドに基づいて動的に表示内容を更新するシンプルなWebアプリです。ユーザーが入力した値が、下部にリアルタイムで反映されます。

プログラムの解説

1. Dashのインポート
import dash
from dash import dcc, html
from dash.dependencies import Input, Output

まず、dashライブラリとその関連モジュールをインポートしています。dashはインタラクティブなWebアプリケーションを構築するためのフレームワークです。dccはDash Core Components、htmlはHTMLタグを生成するためのモジュールです。また、dash.dependenciesからInputOutputをインポートしていますが、これらはコールバック関数で使われる、入力と出力を定義するためのモジュールです。

2. アプリケーションインスタンスの作成
app = dash.Dash(__name__)

ここでdash.Dash(__name__)により、Dashアプリケーションのインスタンスappを作成します。これによって、Dashアプリケーションが起動可能になります。

3. アプリのレイアウト
app.layout = html.Div([
    html.H1("Dash基本アプリ"),
    dcc.Input(id='input-box', value='初期値', type='text'),
    html.Div(id='output-box')
])

app.layoutはアプリケーションのUIを定義します。この例では、html.Divを使って、アプリ全体のコンテナを作り、その中にhtml.H1dcc.Input、およびhtml.Divの3つの要素が入っています。

  • html.H1("Dash基本アプリ")は、タイトルとして「Dash基本アプリ」というテキストを表示します。
  • dcc.Input(id='input-box', value='初期値', type='text')は、テキスト入力フィールドを表示します。このフィールドには、id='input-box'という識別子が付けられており、初期値として'初期値'が設定されています。type='text'は、標準のテキスト入力タイプを指定しています。
  • html.Div(id='output-box')は、入力された値を表示するための領域です。ここでもid='output-box'が付けられています。
4. コールバック関数
@app.callback(
    Output('output-box', 'children'),
    [Input('input-box', 'value')]
)

ここでコールバックが定義されています。Dashでは、UIのインタラクションに応じて動作するコールバック関数を使います。このコールバック関数は、@app.callbackというデコレータを使って定義され、次の2つの要素があります。

  • Output('output-box', 'children'): 出力です。ここでは、id='output-box'の要素(html.Div)のchildren(中身のコンテンツ)を更新します。
  • [Input('input-box', 'value')]: 入力です。id='input-box'のテキスト入力フィールドの値(value)がコールバック関数の引数として渡されます。
5. コールバック関数の定義
def update_output(value):
    return f'入力された値: {value}'

この関数は、input-boxに入力されたテキストを受け取り、output-boxに「入力された値: {value}」という形式で表示します。たとえば、テキストボックスに「こんにちは」と入力すると、「入力された値: こんにちは」というメッセージが表示されます。

6. アプリの起動
if __name__ == '__main__':
    app.run_server(debug=True)

if __name__ == '__main__':という条件分岐で、スクリプトが直接実行されたときにアプリケーションを起動します。app.run_server(debug=True)は、デバッグモードでサーバーを起動するためのコマンドです。デバッグモードを有効にすると、コードの変更が自動的に反映され、エラー情報も詳しく表示されます。

Dashの参考リンク
  • Dash公式ドキュメント: Dashの基本的な使い方やコールバックの仕組みについて詳しく説明しています。
  • Dash Layout: HTMLコンポーネントを使ったレイアウト構築に関する情報です。
  • Dash Callbacks: コールバックの詳細な動作についてのドキュメントです。

グラフの可視化

import dash
from dash import dcc, html
import plotly.express as px

app = dash.Dash(__name__)

# サンプルデータ
df = px.data.iris()

fig = px.scatter(df, x='sepal_width', y='sepal_length', color='species')

app.layout = html.Div([
    html.H1("Irisデータセットの散布図"),
    dcc.Graph(id='scatter-plot', figure=fig)
])

if __name__ == '__main__':
    app.run_server(debug=True)

説明: このアプリケーションでは、Plotlyを使ってIrisデータセットの散布図を表示しています。Dashを使って簡単にデータビジュアライゼーションが実装できることを示しています。

プログラムの解説

1. DashとPlotlyのインポート
import dash
from dash import dcc, html
import plotly.express as px

まず、dashライブラリをインポートし、dcc(Dash Core Components)とhtml(HTMLコンポーネント)モジュールを使ってアプリケーションのUIを構築します。また、plotly.express(略してpx)は、データの可視化に特化したライブラリで、簡単な関数呼び出しでグラフを作成できます。

2. Dashアプリケーションのインスタンス作成
app = dash.Dash(__name__)

ここで、dash.Dash(__name__)によってDashアプリケーションのインスタンスを作成しています。このインスタンスが、アプリ全体を管理する中心的な役割を果たします。

3. データの読み込みとグラフの作成
df = px.data.iris()
fig = px.scatter(df, x='sepal_width', y='sepal_length', color='species')
  • px.data.iris()は、Plotly Expressに組み込まれているIrisデータセットを取得する関数です。このデータセットは、アヤメ(Iris)の花のデータを含んでおり、3つの異なる種(species)に分類されています。それぞれのデータには、がく片(sepal)や花弁(petal)の幅や長さが含まれています。
  • px.scatter()は散布図を作成する関数です。ここでは、sepal_width(がく片の幅)をX軸、sepal_length(がく片の長さ)をY軸としてプロットし、色でspecies(種)を区別しています。この関数はインタラクティブな散布図を簡単に生成します。
4. アプリケーションのレイアウト設定
app.layout = html.Div([
    html.H1("Irisデータセットの散布図"),
    dcc.Graph(id='scatter-plot', figure=fig)
])
  • html.Div()は、全体のコンテナ要素を作成しています。このコンテナの中に、html.H1("Irisデータセットの散布図")でタイトルを表示し、dcc.Graph()でグラフを表示しています。
  • dcc.Graph()は、PlotlyのグラフをDashアプリに埋め込むためのコンポーネントです。この例では、id='scatter-plot'として識別子を付け、figure=figとして、先ほど作成した散布図figを表示します。
5. アプリの実行
if __name__ == '__main__':
    app.run_server(debug=True)

この部分は、スクリプトが直接実行されたときにDashアプリを起動するためのものです。app.run_server(debug=True)によって、デバッグモードでサーバーが起動されます。デバッグモードでは、コードの変更が自動的に反映され、エラー情報も詳細に表示されます。

DashとPlotly Expressの基本的な流れ

このプログラムでは、Dashを使ってIrisデータセットの散布図をWebアプリとして表示する方法を示しています。DashはアプリケーションのUIを構築し、Plotly Expressがデータの可視化をサポートしています。

  • dcc.Graph()を使うことで、作成したグラフを簡単に表示できます。さらに、Plotlyのグラフはインタラクティブなので、ユーザーがマウスオーバーやズームイン・アウトといった操作を行うことが可能です。
  • グラフやデータをダイナミックに更新したい場合は、コールバック関数を使ってリアルタイムでデータを更新することが可能です。Dashのコールバックに関してはこちらを参考にしてください。
参考リンク

コールバックを利用したインタラクティブなグラフ更新

import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.express as px

app = dash.Dash(__name__)

# サンプルデータ
df = px.data.gapminder()

app.layout = html.Div([
    html.H1("年ごとの人口データ"),
    dcc.Dropdown(
        id='year-dropdown',
        options=[{'label': str(year), 'value': year} for year in df['year'].unique()],
        value=1952
    ),
    dcc.Graph(id='population-graph')
])

@app.callback(
    Output('population-graph', 'figure'),
    [Input('year-dropdown', 'value')]
)
def update_graph(selected_year):
    filtered_df = df[df['year'] == selected_year]
    fig = px.scatter(filtered_df, x='gdpPercap', y='pop', size='pop', color='continent',
                     hover_name='country', log_x=True, size_max=60)
    return fig

if __name__ == '__main__':
    app.run_server(debug=True)

説明: ユーザーがドロップダウンメニューから特定の年を選択すると、その年のデータに基づいてグラフが更新されるインタラクティブなアプリケーションです。Dashのコールバック機能を活用し、リアルタイムでグラフを更新する方法を示しています。

プログラムの解説

1. DashとPlotlyのインポート
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.express as px
  • dashライブラリをインポートし、dcc(Dash Core Components)とhtml(HTMLコンポーネント)モジュールを使ってアプリケーションのUIを構築します。
  • dash.dependenciesInputOutputは、コールバックで使われる入力と出力の定義に使用されます。
  • plotly.express(略してpx)は、簡単にデータ可視化を行うためのPlotlyライブラリです。
2. Dashアプリケーションのインスタンス作成
app = dash.Dash(__name__)

dash.Dash(__name__)でDashアプリケーションのインスタンスを作成しています。このインスタンスがアプリ全体を管理します。

3. データの読み込み
df = px.data.gapminder()

px.data.gapminder()は、Plotly Expressに組み込まれているGapminderデータセットを読み込む関数です。このデータセットには、各国の年ごとの人口やGDP、平均寿命などの情報が含まれています。複数の年(1952年から2007年まで)のデータが含まれており、これを使って視覚化を行います。

4. アプリケーションのレイアウト設定
app.layout = html.Div([
    html.H1("年ごとの人口データ"),
    dcc.Dropdown(
        id='year-dropdown',
        options=[{'label': str(year), 'value': year} for year in df['year'].unique()],
        value=1952
    ),
    dcc.Graph(id='population-graph')
])
  • html.Div()は、全体のコンテナとして機能し、その中にhtml.H1dcc.Dropdowndcc.Graphの3つのコンポーネントを含んでいます。
  • html.H1("年ごとの人口データ")はアプリケーションのタイトルとして表示されます。
  • dcc.Dropdown()は、年を選択するためのドロップダウンメニューを表示します。
  • id='year-dropdown'はこの要素の識別子です。
  • optionsには、ユニークな年(1952年から2007年まで)のリストが渡されます。これにより、各年が選択肢として表示されます。
  • value=1952は初期値として1952年を選択する設定です。
  • dcc.Graph(id='population-graph')は、選択した年に基づく散布図を表示するための要素です。
5. コールバック関数
@app.callback(
    Output('population-graph', 'figure'),
    [Input('year-dropdown', 'value')]
)
def update_graph(selected_year):
    filtered_df = df[df['year'] == selected_year]
    fig = px.scatter(filtered_df, x='gdpPercap', y='pop', size='pop', color='continent',
                     hover_name='country', log_x=True, size_max=60)
    return fig
  • @app.callbackでは、出力と入力を指定してコールバック関数を定義します。コールバックは、ユーザーがUI上で行う操作に応じて、動的にグラフを更新するための仕組みです。
  • Output('population-graph', 'figure')は、グラフのfigure属性(中身)を更新する出力です。
  • [Input('year-dropdown', 'value')]は、ドロップダウンメニューで選択された年の値を入力として受け取ります。
  • update_graph関数は、選択された年(selected_year)を引数に受け取り、その年に該当するデータをフィルタリングします。
  • filtered_df = df[df['year'] == selected_year]は、Gapminderデータセットから選択した年のデータのみを抽出しています。
  • px.scatter()で、フィルタリングされたデータに基づいて散布図を作成します。X軸にGDP(gdpPercap)、Y軸に人口(pop)、点のサイズも人口(pop)を反映させています。また、colorで各大陸を色分けし、hover_nameで国名をホバー表示します。log_x=TrueはX軸を対数スケールに設定するオプションで、size_max=60は点のサイズの最大値を設定しています。
6. アプリの実行
if __name__ == '__main__':
    app.run_server(debug=True)

スクリプトが直接実行された場合、app.run_server(debug=True)によりアプリがデバッグモードで起動します。デバッグモードでは、変更が即座に反映され、エラー情報も詳細に表示されます。

まとめ

このプログラムは、Dashを使って年ごとの人口とGDPの関係を視覚化するアプリケーションを構築しています。ユーザーはドロップダウンメニューから特定の年を選択し、その年のデータを視覚化した散布図がリアルタイムで更新されます。Dashのコールバック機能を使って、インタラクティブなUIを実現しています。

参考リンク

まとめ

Dashは、データサイエンティストやエンジニアにとって、手軽にインタラクティブなWebアプリケーションを作成できるツールです。シンプルな構文ながらも強力な機能を持ち、さまざまな分野での活用が期待されます。ただし、大規模アプリケーションやモバイル対応には注意が必要です。

Dash関連記事まとめ

DashはJavaScriptライブラリであるReactの上に構築されたPythonフレームワークであるが、DashはRでも動作し、最近ではJuliaもサポートしている。
Wikipedia – Plotly/Dash から引用、翻訳

コメント

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