Streamlit+Plotlyでガントチャート付きのタスク管理アプリ

お疲れ様です。

Streamlitを使ってガントチャート付きのタスク管理アプリを作ったので紹介。 図の表示にはPlotlyを使用して動的なガントチャートにしています。(Plotlyの勉強も兼ねています。)
職場のタスク管理用のツールがExcelシートのままなのでゆくゆくはこちらに置き換えられたらなと思っています…!

ソースコード

GitHubソースコードを上げていますので、コードを詳しく見たい方はこちらへ。 これからも順次更新していくつもりなので記事を書いた時点でのバージョンをタグで残しています。

github.com

アプリの見た目

今回は簡単にガントチャートの部分とタスクリストを表示するテーブルを作成しました。

データ形式

データは以下のようなcsvファイルを作成して使用します。このうち「ラベル」、「開始日」、「終了日」、「状況」の列はガントチャートの作成に必須になります。タスク内容の部分は現状タスクリストのテーブルで表示するのみの想定で自由記述欄的な感じです。

ガントチャート

公式の解説を参考に作成。ガントチャートもそうですが、こうやっていろんなタイプのグラフのチュートリアルがあるのはありがたいです。

plotly.com

データを表示する際は、csvを読み込んだだけのDataFrameからガントチャートの関数に合わせたDataFrameの形式に合わせる必要があります。
dict(Task=task, Start=start, Finish=finish, State=state)のリストをDataFrameに変換した形にします。

# DataFrameの形式変換
plot_df = pd.DataFrame([
    dict(Task=task, Start=start, Finish=finish, State=state)
    for task, start, finish, state 
    in zip(task_df["ラベル"], task_df["開始日"], task_df["終了日"], task_df["状況"])
])

変換したデータでガントチャートを作成します。colorsとindex_colを指定して状況を色分けするように設定しています。

COLORS = {
    "完了": "rgb(0, 0, 150)", 
    "作業中": "rgb(0, 0, 50)", 
    "予定": "rgb(0, 0, 250)"
}

# ガントチャートを作成
fig = ff.create_gantt(plot_df, colors=COLORS, index_col='State', 
                                 show_colorbar=True, group_tasks=True)

スライダーを使って表示範囲を変えたり、スクロールできるように工夫しています。 また、左上のボタンで表示範囲を変えることも可能です。 今回用意したデータがそれほど多くないのでボタンは少ないですが、必要に応じて追加していきたいです。
この辺の細かい設定はFigureを作成した後にlayoutを更新して設定します。

fig.update_layout(
    xaxis=dict(
        rangeselector=dict(
            buttons=list([
                dict(count=1, label="1ヶ月", step="month", stepmode="backward"),
                dict(count=3, label="3ヶ月", step="month", stepmode="backward"),
                dict(step="all", label="全体表示")
            ])
        ),
        rangeslider=dict(visible=True),  # スライダー表示
        type="date"
    )
)

テーブル

Streamlitの機能でDataFrameをテーブルで簡単に表示することができます。今回初めて使いましたが、DataFrameをそのまま表示できて簡単なソート機能などもついていてかなり便利だなと感じました。

docs.streamlit.io

コードとしては一旦これだけ。csvを読み込んだままの表示です。さらなるカスタマイズもできるそうですが今のところは不要かなと思っています。

# DataFrameを表示
st.dataframe(STATE.tasks_df)

※続きの記事 fallpoke-tech.hatenadiary.jp