7rikazhexde’s tech log

技術的な興味関心、備忘録、アウトプットなどを書いています。

【Python】Dashを使用してPlotlyのDatasetsをDownloadするWebアプリについて

2023年最初の記事になります。今年はデータ分析のスキルを上げたいと思い、実際にプログラムを作成して学んでいこうを考えています。

今回はPythonのDashライブラリを使用してローカルWebサーバーを起動してPlotlyのDatasetsをDownloadするDashアプリを作成したので紹介します。

概要

はじめに、データ分析について調べるとPythonでPlotly社が提供しているオープンソースのライブラリが公開されており、グラフ作成向けのライブラリであるPlotlyとデータ可視化用のWebアプリを作るためのライブラリ(フレームワーク)であるDashを使用することで、データの抽出から可視化をセットにしたダッシュボードを作成できることがわかりました。

Dash公式ページにはUser Guideがあり、Dash Callbacksまで読めばインタラクティブダッシュボードを作成することができます。また、Plotly Commnity Forumには運営やユーザーから仕様に関する情報が投稿されており、疑問点や不明点についても共有されています。

今回は実際にUser Guideを読んで、Dashライブラリを使用してローカルWebサーバーを起動してPlotlyのDatasetsをDownloadするWebアプリを作成したので紹介します。

Webアプリについて

dashモジュールを使用して作成したdashアプリからPlotlyのリポジトリからdataset(rawファイル)を取得します。

取得したdatasetはdash_tableモジュール で作成したtableで表示してbuttonをトリガーにcsvファイルを保存します。

<注意事項>
datasetはリポジトリ以下のcsvファイルが対象ですが、フォルダに保存されたファイルは対象外となりますのでご理解ください。

デモ動画

ソースコードGitHubに公開しています。

github.com

仕様について

  • dcc.Dropdownクラスを使用してPlotlyのdatasets(ファイル名)を保持するリストを選択すると対応するURLを作成してpandas.read_csvメソッドをコールしてDataFrameオブジェクト(df)を作成する
  • 作成したdfをdash_table.DataTableクラスのcomponent_property(columnsとdata)指定で更新してテーブル表示する
  • セルを選択するとSelect Table Dataに選択したセルのデータをpandas.DataFrame.ilocメソッドで抽出して表示する
  • ページを切り替えた場合はSelect Table Dataに'No data selection'を表示する
  • CSV Downloadのボタンを選択するとTableに表示されたデータをsave as指定でcsvファイルで保存する

CallBack処理について

以下ではDash Dev Toolsで作成するCallback Graphを例に説明します。

<補足>
Dash Dev Toolsの各機能の詳細はConfiguring Dash Dev Tools & app.run_server Referenceに記載されています。

初回起動時

コールバック処理はコールバック関数でinputをトリガーにしてoutputに対して実行します。
ここで、灰色の矢印がinput、青色の矢印がoutputに対応します。
それぞれ、HTMLの各タグに対してcomponent_propertyを設定することでレイアウトに合わせたコールバック処理を実装することができます。

dash_table.DataTableオブジェクトはレイアウト作成時(Dashオブジェクト作成)に作成しますが、style属性を'none'にして非表示にします。

選択したセルを表示するdata_table_outはactive_cell(セルの値)とpage_current(ページの値)をトリガーに更新します。それぞれテーブル表示時は'null'になっています。

セル選択時はactive_cellトリガーが起動し、選択したセルの値を表示します。ページ遷移時に起動するpage_currentトリガーではセルの値をデフォルト値に戻しています。

page_currentトリガーを追加した理由はページ遷移により遷移前のセル情報の表示が残るため、トリガーで意図的にデフォルト値に戻す処理を実行しています。

データセット選択時

dcc.Dropdownからデータセットを選択すると対応するデータセットのファイル名をid='drop_down_div'のvalue属性が更新されます。

dcc.Dropdownをトリガーにデータセットのファイル名からURLを作成し、pandas.read_csvメソッドをコールしてDataFrameオブジェクト(df)を作成します。

また、作成したdfをdata_tableで定義するcomponent_propertyに設定し、コールバック関数の戻り値に設定します。

ここで起動時に設定したstyle属性を'inline'に変更してテーブルを表示します。

合わせてユーザがどのページにいるのかを表す'page_current'をトリガーにid='data_table_out'のchildrenを'No data selection'に更新し、セルの値を表示します。(page_currentには0が設定されます。)

セル選択時

セル選択時、id='data_table'のselected_cellsが更新されます。

セル選択をトリガーにid='data_table_out'のchildrenをセルの値で更新します。

また、ページを変更すると'page_current'をトリガーにセルの選択の解除とid='data_table_out'のchildrenを'No data selection'に更新し、セルの値を表示します。(page_currentには変更したページ数-1の値が設定されます。)

CSV Downloadボタン選択時

CSV Downloadボタンを選択するとdfを基に作成されたテーブルのデータがcsvファイルで保存されます。

保存する際のファイル名はPlotlyのデータセットのファイル名に合わせるためにpyperclipモジュールを使用してクリップボードにコピーします。

ファイル名はデフォルトで'Data.csv'となっているため、変更方法を調査したところdcc.Dropdownのcomponent_propertyからテキストデータを取得することができなかったため、pyperclipモジュールを使用することにしました。

また、本アプリではCSV Downloadボタンを使用していますが、これは個別に作成しています。

と言うのも、dash_tableではexport_formatを設定するとclass='export'を持つbutton要素が作成されます。ただし、buttonタグのchildren属性はexportとなっており、data_tableのcomponent_propertyからはbuttonタグのchildren属性が存在せず、Pythonコードから変更できないことがわかりました。

個人的にボタンはCSV Downloadとしたかったため別にbutton作成することも考えましたが、dash_tableのcomponent_propertyも活かしたかったのでdash_tableのbuttonを使用する方法で検討しました。

調査するとcustom CSSclientside_callbackメソッドを使用することで対応できることがわかりました。

custom CSSはassets以下にcssファイルを配置するとDashアプリに自動で組み込まれます。

そこで、Python側でid='export_table'のbuttonを追加し、custom.cssを作成して、class='export'を持つbutton要素をdisplay: noneとして非表示にしました。

そして、clientside_callbackメソッドを使用してJavaScript関数をコールバック関数としてコールして、JavaScript関数にquerySelector() メソッドでclass='export'を持つbutton要素のclickイベントを発行します。

また、各コンポーネントPythonコードで変更することができますが、custom.cssでも変更することが可能であり、本アプリでもbutton以外にも定義しています。

以上より、作成したボタンに対して、exportボタンの処理(csvファイルのダウンロード)を有効にしました。

追加情報

以下コミットでdcc.Downloadコンポーネントによるダウンロード処理を追加しました。 github.com

参考: Downloading a Dataframe as a CSV file
dash.plotly.com

dash_table.DataTable(export_format='csv')のコードでは有効にしていませんが、
exportボタンであればテーブルのデータ構造にあわせてデータをDLすることができます。 (例:ソート処理)

dcc.Downloadでは同様の処理を実現する場合はソート後のデータをDL対象にしなければいけない点に注意が必要です。

まとめ

Dashを使用してPlotlyのDatasetsをDownloadするWebアプリについて紹介しました。

User Guideだけではわからない仕様もあったため、Plotly Commnity Forumも参考にしてDatasetsをDLするアプリを作成しました。

今後はPlotlyライブラリも使用してグラフを作成してダッシュボードに組み込んだアプリも作成してみようと思います。

参考記事

以下の記事を参考にさせていただきました。

techblog.cccmk.co.jp

community.plotly.com