数時間でデータアプリを作成するツール


数時間でデータアプリを作成するツールというキャッチフレーズでお馴染みのStreamlitだが,サンプルの例題を解説しているに過ぎないものが(英語を含めても)ほとんどだ.

本家はこちら.

実践的な使用法を自分と学生用にメモしておく.

Streamlitでは上から順に実行して,それをWebに吐き出すのだが,ロジックのコントロールに注意する必要がある.

たとえば,buttonでユーザーがボタンを押したときに,何か実行する(たとえばデータを読み込む)ようなコードを書くと,何か別の操作をして,上から順に実行したときにボタンが押されてないことになってしまう.

したがって,buttonではなくcheckboxを使う方がよい.checkboxはチェックされたか否かが保管されているので,再実行時に前と同様のフローになる.(たとえばデータを読んでくれる.)

#if st.button("button1"):これは良くない.
if st.checkbox("Check2"):
   x = "abc"
   st.write(x)
   df = read_df("KEN_ALL.txt")
   st.write("len=",len(df))
   st.write(df.head())
   st.write( draw(df) )

また,checkboxのブロック内で実行された内容は,次回に保存されている.たとえば,上の変数xはabcのままだ.

上では,日本中の郵便番号データ(KEN_ALL)を読み込んで,それをPlotly Expressで散布図に描画しているのだが,結構時間がかかる.これを毎回するのを避けるためにキャッシュを使う.

@st.cache
def read_df(name):
    return pd.read_csv(name,names=[0,1,2,3,4,5,6,7,"x","y"],
    encoding="shift-jis")

@st.cache
def draw(df):
   return px.scatter(df, x="y", y="x")

上の2つの関数は@st.cacheデコレータがついていて,これでキャッシュ(メモ化のようなものだ)をしてくれるので,2回目以降はは高速になる.

checkboxブロックの後に,ブロック内で処理された地図やデータフレームを使おうとすると,checkboxが押されていない状態のときにエラーする.(たとえば,コードが最初に実行されたとき.)

これを避けるには,コードの最初でオブジェクトにNoneを代入しておいて,Noneでないなら描画や出力をするという風に書けばよい.

 追記:キャッシュ周りはまだバグがあるようだ。キーにタプルを入れた辞書を返り値にするとエラーする。その場合には、キーを文字列に変換するなどの工夫が必要になる。Gurobiのモデルや変数ももちろんハッシュ不能なので、適当な情報に変換してから返す必要がある。

試しに使用した全体のコードは以下のようになる.

import streamlit as st
import pandas as pd 
import time
import numpy as np
import plotly.express as px
@st.cache
def read_df(name):
    #time.sleep(3)
    return pd.read_csv(name,names=[0,1,2,3,4,5,6,7,"x","y"],encoding="shift-jis")
@st.cache
def draw(df):
   return px.scatter(df, x="y", y="x")
df = None

x = 0
if st.checkbox("Check1"):
   x = 123
   st.write(x)
st.write("Outside",x)
#if st.button("button1"):
if st.checkbox("Check2"):
   x = "abc"
   st.write(x)
   df = read_df("KEN_ALL.txt")
   st.write("len=",len(df))
   st.write(df.head())
   st.write( draw(df) )
st.write("Outside2",x)
if st.checkbox("Check3"):
   if df is not None:
       st.write(df.head())


この記事が気に入ったらサポートをしてみませんか?