今回はStreamlitでWebアプリを作成する例として、st.text_inputとst.number_inputを使ってグラフで使用するデータを変えていく方法について紹介します。
汎用的でかつ拡張性のあるアプリを作成する上で、テキストや数値を使用者に入力してもらうことを前提で設計できるようになるとアプリ開発の幅が広がります。
ぜひ試してみてください。
使い方と配置イメージ
★テキスト入力
st.text_input(‘ラベル’, ‘初期文字列’)
★数値入力
st.number_input(‘ラベル’, 最小値, 最大値, 初期値)
簡単に使えます。
実際に今回紹介するアプリではこのような構成で配置していく例を解説します。
それでは、さっそく実際にアプリを作りながら解説していきます。
コードの詳細解説
データ準備
必要なライブラリをインポートします。
import streamlit as st
import plotly.express as px
plotly.expressをインストールしていない方はpipでインストールしてください。
pip install plotly_express
st.titleでタイトルを設置します。
データフレーム(df)にはplotly_expressで用意されているgapminderを使用します。
st.title('一人あたりのGDPと平均寿命、サイズは人口')
df = px.data.gapminder()
エディタはspyderを使っているのでdfの中身が簡単にチェックできます。
↓spyderに関する記事はこちら
gapminderの中には国名(country)、 大陸(continent)、 年度(year)、 寿命(lifeExp)、 人口(pop)、 国民一人あたりのGDP(gdpPercap)、 国の略称(iso_lpha), 国の番号(iso_num)の情報が入っています。
テキスト・数値入力ボックスの設置
先ほどの使い方を参考に国名(テキスト)と年代(数値)を入力するボックスを設置します。
country=st.text_input('国を入力', 'Japan')
year=st.number_input('年(1952~5年おき)',1952,2007,1952,step=5)
サイドバーへ入力ボックスを設置
st.sidebar.●●でサイドバーに設置することもできます。
今回はグラフで示す軸の最大・最小値をサイドバーの入力ボックスで調整できるようにします。
st.sidebar.title('軸の設定')
xmin=st.sidebar.number_input('x最小値:',0,100,0)
xmax=st.sidebar.number_input('x最大値:',0,10000,4000)
ymin=st.sidebar.number_input('y最小値:',0,100,0)
ymax=st.sidebar.number_input('y最大値:',0,100,100)
グラフとの連携部分を作成
入力ボックスに書き込まれた内容を反映して、データフレームの中身が更新されるようにコードを書いていきます。
データフレームの中身をある条件で抽出する方法を使用します。
イコール(==)で絞る基本的な使い方です。
df_px=df[df['year'] ==year]
df_country = df[df['country'] ==country]
df_ano=df_country[df_country['year'] ==year]
グラフの作成
px.scatter()で散布図が書けます。
本内容とは直接関係ないですが、サイズ(size)はプロットの大きさ、hover_nameはカーソルを合わせた時に表示されるデータの指定です。
fig=px.scatter(df_px, x="gdpPercap", y="lifeExp", size="pop", color="continent",hover_name="country",range_x=[xmin,xmax],range_y=[ymin,ymax])
あとはグラフを表示する実行文のみです。
st.plotly_chart()で行います。
use_container_width=Trueとするとグラフの幅が列の長さになるようです。
st.plotly_chart(fig, use_container_width=True)
完成図
おまけ(グラフ上にラベルを表示)
オレンジのテキストつきラベル(選択された国名に応じて変化)を表示するコードはこちらです。
fig.add_annotation(
x=df_ano.iloc[0,5],
y=df_ano.iloc[0,3],
xref="x",
yref="y",
text=country,
showarrow=True,
font=dict(
family="Courier New, monospace",
size=16,
color="#ffffff"
),
align="center",
arrowhead=2,
arrowsize=1,
arrowwidth=2,
arrowcolor="#636363",
ax=20,
ay=-30,
bordercolor="#c7c7c7",
borderwidth=2,
borderpad=4,
bgcolor="#ff7f0e",
opacity=0.8
)
最終コード
import streamlit as st
import plotly.express as px
st.title('一人あたりのGDPと平均寿命、サイズは人口')
df = px.data.gapminder()
country=st.text_input('国を入力', 'Japan')
year=st.number_input('年(1952~5年おき)',1952,2007,1952,step=5)
st.sidebar.title('軸の設定')
xmin=st.sidebar.number_input('x最小値:',0,100,0)
xmax=st.sidebar.number_input('x最大値:',0,10000,4000)
ymin=st.sidebar.number_input('y最小値:',0,100,0)
ymax=st.sidebar.number_input('y最大値:',0,100,100)
df_px=df[df['year'] ==year]
df_country = df[df['country'] ==country]
df_ano=df_country[df_country['year'] ==year]
fig=px.scatter(df_px, x="gdpPercap", y="lifeExp", size="pop", color="continent",hover_name="country",range_x=[xmin,xmax],range_y=[ymin,ymax])
fig.add_annotation(
x=df_ano.iloc[0,5],
y=df_ano.iloc[0,3],
xref="x",
yref="y",
text=country,
showarrow=True,
font=dict(
family="Courier New, monospace",
size=16,
color="#ffffff"
),
align="center",
arrowhead=2,
arrowsize=1,
arrowwidth=2,
arrowcolor="#636363",
ax=20,
ay=-30,
bordercolor="#c7c7c7",
borderwidth=2,
borderpad=4,
bgcolor="#ff7f0e",
opacity=0.8
)
st.plotly_chart(fig, use_container_width=True)
以上で解説は終わりです。