Streamlit を用いたデータ分析アプリ制作

# Streamlit とは

本稿では、[Streamlit](https://www.streamlit.io/) の使い方を説明する。
Streamlit とは、フロントエンドアプリケーションを作成できる python のフレームワークである。Pandas の DataFrame や、 plotly・[altair](https://qiita.com/keisuke-ota/items/80d64153c499c8cc4774) といった描画ライブラリで作成したグラフを埋め込むことができ、工夫次第でデータ分析にも応用することができる。

# 環境
* macOS Catalina (ver.10.15.6)

# インストール

いくつかの方法でインストールすることできる。
1) pip でインストールする。[公式HP推奨](https://docs.streamlit.io/en/stable/)

```terminal:ターミナル
pip install streamlit
```

2) conda で仮想環境を構築する。[公式Forum参照](https://discuss.streamlit.io/t/install-streamlit-with-anaconda/714)

```terminal:ターミナル
conda create -y -n streamlit python=3.7
conda activate streamlit
pip install streamlit
```

# ファイルの実行

Python ファイルを以下のように実行する。

```terminal:ターミナル
streamlit run ファイル名.py
```



# Streamlit の機能

公式 HP の [API reference](https://docs.streamlit.io/en/stable/api.html) に、streamlit の機能がまとめられている。その中でデータ分析に活用できる機能を中心にまとめた。

## タイトルの表示

```python:st_app.py
import streamlit as st
st.title('My app')
```

![スクリーンショット 2020-10-16 23.51.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612858/cf5f2080-d025-d3d5-2790-00c2da362a9f.png)


## 文書の表示

```python:st_app.py
import streamlit as st
st.write("Good morning")
```

![スクリーンショット 2020-10-16 23.51.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612858/ba6292c7-47aa-24e3-a9d8-6e2634693a9d.png)


## DataFrame の表示

```python:st_app.py
import streamlit as st
import pandas as pd
st.table(pd.DataFrame({
    'first column': [1, 2, 3, 4],
    'second column': [10, 20, 30, 40]
}))
```
![スクリーンショット 2020-10-16 23.51.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612858/973f4799-15f8-f5a5-9dae-6afc22abe4c4.png)


## Markdown の表示

```python:st_app.py
import streamlit as st
st.markdown('# Markdown documents')
```


## Plotly の表示

[Plotly](https://plotly.com/python/)は、python 描画ライブラリのひとつで、様々な種類のグラフを作成できる。

```python:st_app.py
import streamlit as st
import plotly.graph_objs as go

animals = ['giraffes', 'orangutans', 'monkeys']
populations = [20, 14, 23]

fig = go.Figure(data=[go.Bar(x=animals, y=populations)])

fig.update_layout(
    xaxis = dict(
        tickangle = 0,
        title_text = "Animal",
        title_font = {"size": 20},
        title_standoff = 25),
    yaxis = dict(
        title_text = "Populations",
        title_standoff = 25),
    title ='Title')

st.plotly_chart(fig, use_container_width=True)
```
![スクリーンショット 2020-10-16 22.42.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612858/8fb30020-f029-fe0d-95a7-6051405c9ef0.png)


## Altair の表示

[Altair](https://altair-viz.github.io/gallery/index.html) は、python 描画ライブラリのひとつで、様々な種類のグラフを作成できる。Pandas の DataFrame でデータを入力するのが特徴である。[【Python】グラフ作成ライブラリ Altair の使い方](https://qiita.com/keisuke-ota/items/80d64153c499c8cc4774) 

```python:st_app.py
import streamlit as st
import altair as alt
from vega_datasets import data

source = data.cars()

fig = alt.Chart(source).mark_circle(size=60).encode(
    x='Horsepower',
    y='Miles_per_Gallon',
    color='Origin',
    tooltip=['Name', 'Origin', 'Horsepower', 'Miles_per_Gallon']
).properties(
    width=500,
    height=500
).interactive()

st.write(fig)
```

![スクリーンショット 2020-10-16 22.56.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612858/37ee08b6-0a23-5563-22d9-bafcc9e47f73.png)

## ボタンの表示

Altair は bool 型を返すボタンを表示させることができる。

```python:st_app.py
import streamlit as st
answer = st.button('Say hello')

if answer == True:
     st.write('Why hello there')
else:
     st.write('Goodbye')
```

【押す前】
![スクリーンショット 2020-10-19 10.00.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612858/03ef9e30-ba45-12ab-5f2e-52261a06cf4c.png)

【押した後】
![スクリーンショット 2020-10-19 10.03.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612858/4ebb39df-094e-ec48-669e-a2836e12b2ef.png)


## チェックボタンの表示

bool 型を返すチェックボタンの表示も可能である。

```python:st_app.py
import streamlit as st
agree = st.checkbox('I agree')

if agree == True :
     st.write('Great!')
```

【チェックなし】
![スクリーンショット 2020-10-19 10.09.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612858/89aa271c-d8d2-37cb-814a-aa62c4219baa.png)

【チェックあり】
![スクリーンショット 2020-10-19 10.11.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612858/a01ca4e8-903d-54bb-9204-666e3211961b.png)

## ラジオボタンの表示

ラジオボタンで要素を選択することも可能である。

```python:st_app.py
import streamlit as st
genre = st.radio(
     "What's your favorite movie genre",
     ('Comedy', 'Drama', 'Documentary'))

if genre == 'Comedy':
     st.write('You selected comedy.')
else:
     st.write("You didn't select comedy.")
```


![スクリーンショット 2020-10-19 10.15.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612858/ad307c8e-a2cf-78eb-14a9-7ac592eaef8c.png)



## ドロップダウンの表示

ドロップダウンから1つだけ選択する場合は以下のとおり。

```python:st_app.py
import streamlit as st
option = st.selectbox(
    'How would you like to be contacted?',
     ('Email', 'Home phone', 'Mobile phone'))
st.write('You selected:', option)
```
![スクリーンショット 2020-10-16 23.46.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612858/fdef5459-fd43-d673-43f5-e3957c12ef96.png)


ドロップダウンから2つ以上同時に選択する場合は以下のとおり。デフォルトで ``Yellow, Red``の2つが選択されている。

```python:st_app.py
import streamlit as st
options = st.multiselect(
    'What are your favorite colors',
    ['Green', 'Yellow', 'Red', 'Blue'],
    ['Yellow', 'Red'])

st.table(options)
```

![スクリーンショット 2020-10-16 23.47.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612858/9d4f252c-1c36-4d38-3a5e-a0369dca82ef.png)


## スライダーの表示

1 つの値を選択する場合は以下のとおり。
以下の例では、最小値0、最大値130、間隔1、初期値25 で動くスライダーを表示させる。

```python:st_app.py
import streamlit as st
age = st.slider('How old are you?',  min_value=0, max_value=130, step=1, value=25)
st.write("I'm ", age, 'years old')
```
![スクリーンショット 2020-10-16 23.14.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612858/a5a1741d-2115-68cc-403e-080340cf230b.png)


2 つの値を選択する場合は以下のとおり。
以下の例では、最小値0.0、最大値100.0、初期値``(25.0,75.0)``で動くスライダーを表示させる。


```python:st_app.py
import streamlit as st
values = st.slider(
    'Select a range of values',
   0.0, 100.0, (25.0, 75.0))
st.write('Values:', values)
```
![スクリーンショット 2020-10-16 23.14.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612858/6b142273-1392-f6fe-468f-ca432346465c.png)

# 応用例
* [scikit-learn を用いたロバスト線形回帰](https://qiita.com/keisuke-ota/items/fdd9c28b648af46d1264)
* [MetaboanalystR を用いたメタボロームデータ解析](https://qiita.com/keisuke-ota/items/803c4299138b169eb9a2)
* [Streamlit による売上データの分析例](https://qiita.com/keisuke-ota/items/87448cdb9479d14240f4)