paloma blog

NWエンジニアやってます。主に自宅環境のお遊びを書きます。Pythonもちょっと。タイトルは好きなカクテルから。

Plotly dashでインプットするファイルを選択できるようにした

身内の麻雀スコアアプリを作ったのですが、今年も新たにスコアを付けていくので年ごとのスコアが見れるようにしたいです。

paloma69.hatenablog.com

ページを分けてもいいんですが、同じレイアウトになってしまうのでファイルを選択してからテーブルやグラフの呼び出しを行うという処理にしたいと思います。

処理概要

  1. ドロップダウンでスコアのcsvファイルを選択
  2. 1を元にスコア一覧表示
  3. 1を元にグラフ表示
  4. 1を元にスコアサマリを表示

コード

ドキュメントを読むとcallbackのidで保持データを連携できるようです。
なので各処理にcallbackのデコレーションを行います。

dashのレイアウト処理は割愛。callbackを抜粋してこんな感じです。

fileinput = dcc.Dropdown(filelist, id='dropdown-data') # ファイル選択処理
--
@callback(
    Output('player-data', 'options'),
    Input('dropdown-data', 'value'), # Inputでデータ連携される
)
def players(value): # 個人スコア用のプレイヤー選択処理
    df = pd.read_csv(value)
--
@callback(
    Output('score-table', 'children'),
    Input('dropdown-data', 'value'),
)
def display_score_table(value): # スコア一覧の表示処理
    df = pd.read_csv(value)
--
@callback(
    Output('tscore-table', 'children'),
    Input('dropdown-data', 'value'),
)
def create_grid_tscore(value): # サマリスコアの作成処理
    tscore = create_tscore_table(value)
--
@callback(
    Output('graph-content', 'figure'),
    Input('dropdown-data', 'value'),
    Input('player-data', 'value'),
)
def display_score_graph(file, player): # グラフ表示の処理

バグ

触った感じ、ファイル選択してから各描画は動いているのですがエラーが表示されます。

画面に表示されているのにcsvが読み込めないとのエラーです。何故だ。

このままではPCのブラウザでは画面見れますが、スマホでは画面が表示されません。
エラーメッセージはpandas関連の様でやはりファイルが読み込めていないんだな。

dashのデバッグモードは優秀で、callbackのやりとりも見えるようになっています。
これを見たらちゃんと連携できていますよね。

エラーメッセージで検索して色々記事を読んだのですがこのへんを読んで一つ思いつきました。

python - pandas read_csv throwing ValueError: Invalid file path or buffer object type: <class 'list'> - Stack Overflow

アプリの立ち上げ時にファイルを読み込もうとしていて未選択状態のため読めないと出ているんではないかと考えました。

改修

アプリ起動時は読み込まないオプションがあるのでこちらを記載。
prevent_initial_call=Trueを入れてあげればいいようです。

@callback(
    Output('player-data', 'options'),
    Input('dropdown-data', 'value'),
    prevent_initial_call=True # ファイル選択してからcallされる
)
def players(value):
    df = pd.read_csv(value)

OK。メッセージ出なくなりました。

まとめ

というわけでアプリの機能追加完了です。
OSSはたくさんのライブラリが絡むので課題が出たら一つずつ地道に探していくしかないですね。
しかしちゃんと動いてよかった。
今年のデータはまだ少ないのでまた仲間と対局をして内容を溜めていきたいと思います。