はじめに
そこまで凝らないWebアプリならStreamlitで簡単に作成でき、無料でデプロイできます。
今回自分が作ったもの:https://formula1-web-app.streamlit.app/
Streamlitとは
Streamlitはpythonだけで簡単にダッシュボードなどのアプリが作れるパッケージ。
pip install streamlit
したら、下記のようなコードを作り、streamlit run app.py
をするだけでWebページが立ち上がるという非常にお手軽なもの。
# app.py(ファイル名は任意)
import streamlit as st
st.write("簡単")
上記は、「簡単」という文字を出力するだけですが、色々な描画を実現するメソッドがあり、それらを組み合わせると簡単にある程度のものを作れます。
Qiita上にもみなさんが記事を書かれていてすぐに参考にできます。
デプロイまでの手順
無料でWebアプリを公開して使えるようにする(=urlでどこからでもアクセスして使う)なら、Streamlit Cloudを使う下記の方法が多分一番簡単だと思います(詳細は後述)。
さもなければ、HerokuやAWSなどのクラウドサービスにお金を払ったりレンタルサーバーを借りたり、といったことをすることに。
1. Githubのアカウントを作成する
Githubの公式ページでSign upします。
開発用という意味だけでなく、Streamlit Cloudでデプロイする際に、連携するので必要です。
2. Streamlitを使ったアプリを作る
Githubでアプリ用のリポジトリを作って、アプリを作ります。
Streamlit公式が、様々な人々が作ったアプリをギャラリーとして出してくれているので、どのようなことがどのようなコードで実現できるのか参考にできます。
※自分は趣味のF1を題材に、過去の結果を見たり、レース戦略をシミュレーションできるアプリを作ってみました(Github、および、アプリ)。
3. Streamlitにアカウントを作る
Streamlitの公式ページでSign upします。
今回は、Streamlit Cloudでデプロイするので、アカウントを持っている必要があります。
4. Streamlit Cloudでデプロイする
Streamlit Cloudは、サーバーを自分で調達したりする必要がなく、無料でアプリを公開することができる非常にありがたいクラウドサービスです。
マシンが強力というわけではないので、メモリやストレージなどを多く使うアプリはデプロイすることはできませんが、普通のダッシュボードや簡単な機械学習アプリなどなら問題なく使えます。
3で作ったStreamlitのアカウントでログインし、デプロイ用のページで、下記のようにアプリを開発したGithubのリポジトリとブランチを選択し、デプロイします。
問題なくデプロイが済めば、そのurlに繋げばいつでもアプリを使えるようになります。
※ずっとアクセスがないとスリープしたり、最終的に削除されます。
作ってみたアプリで使った主なコンポーネントの紹介
今回、主に使用したStreamlitのメソッドの概要を紹介します。
詳細は、Githubを見てみてください。
ダッシュボード部分
図の描画
Streamlitではplotlyのインタラクティブな図をアプリに埋め込むことができます。
下記のようにplotlyのfigureを定義して、st.plotly_chart
で描画できます。
fig = px.line(
df_season_drivers,
x="round",
y="points",
color="driverRef",
labels={"driverRef": "driver", "name": "Grand Prix"},
category_orders={"driverRef": list_order_points},
)
st.plotly_chart(fig, use_container_width=True)
データの選択
また、データのどの部分を示すか(今回のF1アプリの例では、どのシーズンの、どのドライバーの結果を表示するか)をユーザが決められるように、選択機能を使っています。
st.selectbox
やst.multiselect
で入力コンポーネントを作り、値を受け取ることで、先ほどのplotlyで示すデータの範囲をコントロールできます。
selected_season = st.selectbox(
"Select season", list_season, key="selected_season_season_result"
)
df_season = df[df["year"] == selected_season]
selected_items = st.multiselect(
"Select drivers (default = top 5 of the season)",
options=list_drivers,
default=list_default_drivers,
key="selected_drivers_season_result",
)
df_season_drivers = df_season[df_season["driverRef"].isin(selected_items)]
これらを組み合わせることで、このようなダッシュボードが作れます。
シミュレーション部分
入力値の取得
dataframeの単純な描画だけでなく、ユーザからのパラメタ入力値を受けて、何らかの計算をし、その結果を返す、といったような処理もできます。
今回はレース戦略を計算するためのパラメタをst.number_input
で受け取っています。
st.columns
など、各入力コンポーネントの位置を調節することができるコンポーネントがあり、UIを向上させるために工夫できます。
col_1, col_2, col_3, col_4 = st.columns(4)
with col_1:
total_lap = st.number_input(
label="Total race laps", value=60, min_value=0, max_value=100, step=1
)
with col_2:
pitloss = st.number_input(
label="Pitloss(sec)",
value=25.0,
min_value=0.0,
max_value=100.0,
step=0.1,
format="%.1f",
)
~略~
トリガーによって、最適なレース戦略を計算
あるきっかけによって、ある処理を行うといったことをst.button
で実現できます。
今回は、ボタンが押されたら、上記st.number_input
で受け取ったパラメタたちを自前の関数に与えて、レースの最適戦略を計算し、図として表示します。
if st.button("Calculate optimal strategy!"):
# get optimal strategy based on given tyre combination
df_res = _get_optimization_results(
pitloss=pitloss,
total_lap=total_lap,
dict_degradation=dict_degradation,
dict_pace=dict_pace,
track_improvement=track_improvement,
fuel_effect=fuel_effect,
dict_tyre_combi=dict_tyre_combi,
)
これらの処理により、「Calculate optimal strategy!」ボタンが押されると関数が走り、
最適戦略の計算結果を表示する、といった処理をStreamlitで実現できます。