目次
・最初に
・Streamlitとは
・作ったもの
・アプリ概要
・アプリ制作をしてみた所感
・最後に
・宣伝
最初に
本記事ではstreamlitのアプリを作成してみたので、実際のアプリと使用した技術について説明します。
Streamlitとは
StreamlitはPythonのみでアプリケーションを作成できるオープンソースのフレームワークです。
HTML/CSS/Javascriptの知識なしで簡単にアプリケーションを作成できます。
Streamlitの特徴は以下です。
- Pythonだけで完結
- グラフや表の表示が簡単
- セットアップが最小限ですぐ動作する
- 豊富にウィジェット(スライダーやセレクト)が用意されている
↓公式サイトです
↓以下参考にしたサイトです。
作ったもの
Seaborn オープンデータ内容確認サイト
↓アプリのリンクです。こちらでアプリの操作ができます!
アプリ概要
アプリ機能概要
アプリの内容としてはpythonのライブラリであるseabornで提供されているデータの内容を表形式とグラフ形式で確認できるアプリです。
今回のアプリではTipsとTitanicのデータを利用できます。
↓seabornの提供データの詳細は以下です。
https://github.com/mwaskom/seaborn-data/tree/master
このアプリでは以下の機能が利用できます。
① データを表形式で確認
② カテゴリ変数にグループ分けした統計量(合計や平均)を表示
③ ②の数値をグラフで確認
プログラムのフロー
以下プログラムの簡単なフロー画像です。
使用ライブラリ
使用したライブラリは以下の通りです。
・streamlit
・pandas
・numpy
・seaborn
・plotly
それぞれの用途は以下の通りです。
streamlit
→アプリフレームワーク用
pandas・numpy
→データ加工・表の表示用
seaborn
→データ抽出用
plotly
→グラフ可視化用
※当初seabornで可視化をしようとしましたが、
うまくいかなかったためplotlyで試してみました。
以下の強みがあるため、最終的にplotlyを採用しています。
・インタラクティブにグラフを操作できる(グラフのズームやホバー操作など)
・デザインが洗練されている(モダンな見た目)
プログラムコード
以下がPythonのコードとなります。
https://github.com/isomu03/streamlit_graph_viz/blob/main/streamlit_graph_viz.py
# ライブラリ
import streamlit as st
import pandas as pd
import numpy as np
import seaborn as sns
import plotly.express as px
# ヘッダー
st.header("Seaborn オープンデータ内容確認サイト")
st.write("seabornで提供されているデータの内容をグラフで確認するサイトです")
# タブを作る
tab1,tab2 = st.tabs(["Tips","Titanic"])
###### 関数
# category_optionsごとにグループ化してstatisticで選んだ統計量を出力
def make_columns(main_data,category_options,num_options,static,all_columns):
select_all_columns = []
select_all_columns.extend(category_options)
select_all_columns.extend(num_options)
drop_columns = [ i for i in all_columns if i not in select_all_columns]
main_group_0 = main_data.drop(columns=drop_columns)
if static == '合計':
output_group = main_group_0.groupby(category_options,as_index=False).sum()
elif static == '中央値':
output_group = main_group_0.groupby(category_options,as_index=False).median()
elif static == '平均値':
output_group = main_group_0.groupby(category_options,as_index=False).mean()
elif static == '最小値':
output_group = main_group_0.groupby(category_options,as_index=False).min()
elif static == '最大値':
output_group = main_group_0.groupby(category_options,as_index=False).max()
return output_group
#棒グラフを作成する関数
def show_graph(category_options,num_options,fig_data_group):
# カテゴリ変数が複数ある場合
if len(category_options) >= 2:
# 数値尺度の数によってグラフを複数作る
for i in range(0,len(num_options)):
# 棒グラフ作成
fig_group = px.bar(
fig_data_group,
x=category_options[0],
y=num_options[i],
color= category_options[1],
text_auto=True, # 棒の上に値を表示
barmode = 'relative'
)
# 3. Streamlitで表示
st.plotly_chart(fig_group, use_container_width=True)
# カテゴリ変数が一つの場合
elif len(category_options) == 1:
# 数値関数の数によって複数グラフを作る
for i in range(0,len(num_options)):
# 棒グラフ作成
fig_group = px.bar(
fig_data_group,
x=category_options[0],
y=num_options[i],
color= category_options[0],
text_auto=True, # 棒の上に値を表示
barmode = 'relative'
)
# 3. Streamlitで表示
st.plotly_chart(fig_group, use_container_width=True)
else:
st.write('不具合が発生しております。ご不便をおかけし申し訳ございません')
# Tipsデータタブ
with tab1:
#データの概要を説明
st.subheader("データの概要")
# 文章を挿入
st.write('''
あるウェイターがあるレストランで数ヶ月間勤務する間に受け取ったチップに関する情報を記録したデータです。 \n
\n \n
以下変数一覧です \n
・tip:ドルでのチップ \n
・total_bill:ドル建ての請求書 \n
・sex:請求書支払者の性別 \n
・smoker:パーティーに喫煙者がいたかどうか \n
・day:曜日 \n
・time:時間帯 \n
・size: パーティーの規模 \n \n \n
''')
# データを表示
st.subheader("データを表示")
# データを表示(今回はseabornのtipsデータを表示)
st.write("seaborn tipsデータ")
tips = sns.load_dataset("tips")
# データを表示
st.dataframe(tips)
# グラフを表示のサブヘッダー
st.subheader("カテゴリごとの統計量を表示")
#数値指標を選択
num_options = st.multiselect(
'調べたい数値尺度を選択してください',
['total_bill','tip','size']
)
#カテゴリーを選択
category_options = st.multiselect(
'調べたいカテゴリ変数を選んでください',
['sex','smoker','day','time']
)
#統計量を決める
statistic = st.selectbox(
'調べたい統計量を選んでください',
['最大値','最小値','平均値','中央値','合計']
)
all_columns_tips = ['total_bill','tip','size','sex','smoker','day','time']
# グラフと表を表示
if len(category_options) >= 1 and len(num_options) >= 1 and len(statistic) >= 1:
# グラフ作成用の表を作成する
tips_group = make_columns(tips,category_options,num_options,statistic,all_columns_tips)
# 作成した表を出力
st.dataframe(tips_group)
show_graph(category_options,num_options,tips_group)
else:
st.write('※指標を指定しないとグラフは表示されません')
# タイタニックデータタブ
with tab2:
# データの概要
st.subheader("データの概要")
st.write('''
タイタニック号の沈没事故で生存したかどうか、以下の変数で分類したデータになります。 \n
\n \n
以下変数一覧です \n
・alive:生存したかどうか(0=No,1=Yes) \n
・pclass:チケットクラス(1 = 1st, 2 = 2nd, 3 = 3rd)\n
・class:チケットクラス
・age:年齢 \n
・sex:性別 \n
・who:男女どっちか \n
・adult_male:成人男性がどうか \n
・sibsp:タイタニック号に乗船していた兄弟姉妹/配偶者の数 \n
・parch:タイタニック号に乗船していた親と子供の数 \n
・ticket:チケット番号 \n
・fare: 運賃 \n
・ticket:チケット番号 \n
・cabin:船室番号 \n
・deck:乗船デッキ \n
・embarked:乗船港(C = シェルブール、Q = クイーンズタウン、S = サウサンプトン) \n \n \n
''')
# データを表示
st.subheader("データを表示")
# データを表示(今回はseabornのtipsデータを表示)
st.write("seaborn Titanicデータ")
titanic = sns.load_dataset("titanic")
st.dataframe(titanic)
# グラフを表示
st.subheader("カテゴリごとの統計量を表示")
#数値指標を選択
num_options_titanic = st.multiselect(
'調べたい数値尺度を選択してください',
['survived','age','parch','fare','sibsp'],
key='titanic_num_option'
)
#カテゴリーを選択
category_options_taitanic = st.multiselect(
'調べたいカテゴリ変数を選んでください',
['pclass','sex','embarked','class','adult_male','deck','embark_town','alive','alone','who'],
key='titanic_category_option'
)
#統計量を決める
statistic_titanic = st.selectbox(
'調べたい統計量を選んでください',
['最大値','最小値','平均値','中央値','合計'],
key='titanic_static_option'
)
all_columns_titanic = ['survived','age','parch','fare','sibsp','pclass','sex','embarked','class','adult_male','deck','embark_town','alive','alone','who']
# グラフと表を作成
if len(category_options_taitanic) >= 1 and len(num_options_titanic) >= 1 and len(statistic_titanic) >= 1:
# グラフ作成用の表を作成する
titanic_group = make_columns(titanic,category_options_taitanic,num_options_titanic,statistic_titanic,all_columns_titanic)
# 作成した表を出力
st.dataframe(titanic_group)
show_graph(category_options_taitanic,num_options_titanic,titanic_group)
else:
st.write('※指標を指定しないとグラフは表示されません')
デプロイサーバーについて
今回はStreamlit CloudからPythonプログラムをデプロイ・公開しました。
GithubリポジトリにソースコードをアップロードしてStreamlit Cloudと連携することでデプロイができます。
↓以下参考にしたサイトです
アプリ制作をしてみた所感
初めてPythonでアプリ制作をしたため、自分が感じたStreamlitの利点と躓いた点を説明します。
Streamlitの利点
利点としては以下2点かなと思っています。
①ファイル数が少ない
他のwebアプリは業務で扱ったことがないですが、StreamlitはPythonファイル1ファイルでも動くのでかなり導入が簡単でした。
②Pythonのみで動く
Streamlitの概要でも説明しましたが、HTML/css/javascriptのことを考えなくても良いので、導入ハードルが低いです。
躓いた点
逆に躓いた点は以下3点になります。
①Streamlitと相性の良い・悪いグラフライブラリがある
単に知識不足だけだったのかもしれませんが、なぜかSeabornでグラフを出力できなかったので、plotlyで試したところうまくいきました。
plotly以外にもstreamlit側でサポートしているグラフライブラリはいくつかあるようなので、グラフライブラリに迷った際は以下の記事を見てみてください。
②可読性が悪くなりがち
記述ルールがそんなに厳しくないため、スパゲッティコードになりやすい構造になっていると感じました。
よって、大規模開発を行う場合は以下のような対応を実施したほうが良い認識です。
・記述ルールが緩いので開発チーム内で記述ルール等は徹底した方がいい
・大規模開発なら処理単位でモジュール化した方がいい
③デプロイ時requirements.txtファイルがいる
アプリをstreamlit Cloudにデプロイする際、呼び出しているライブラリをreaquirements.txtに記述してGithubにアップロードしなければいけません。
最初これが原因のエラーを見た時は何のことか分からず焦りました。
最後に
ここまで読んでいただきありがとうございました。
今回webアプリを初めて作成しましたが、業務での経験がなかったため、
新鮮な体験でなかなか面白かったです。
また、python1ファイルで作成できるので、スパゲッティコードになりやすい構造だと感じました。
(実際スパゲッティコードになってますね💦)
モジュール化をすることでコードをわかりやすくできると思うので、可読性の観点は改善の余地があると思っています。
今後の対策としては、細々した処理をモジュール化してコードの可読性を上げるか他のライブラリでも同じようなことができるかを試してみようと思います。
今回作ったアプリについてもTipsとTitanic以外にも順次追加していきます。
何かアプリについてアドバイスや質問などがありましたらコメントをいただけますと幸いです。
宣伝
株式会社ジールはMicrosoft Azure やAWS(Amazon Web Services)、Google Cloud Platform(GCP)、Oracle Cloud Infrastructure(OCI)など、多彩なクラウドプラットフォーム構築・運用の知見を有しています。そのため、複数のクラウドサービスを組み合わせるマルチクラウド環境においても、ベンダーロックインを回避し、お客様のご要望に応じた最適なクラウドプラットフォームの構築・運用への対応が可能です。
