Dashでウェブアプリ作成①

# はじめに

データの基礎分析や分類モデルなどを作成したものをアプリ上で見せたり触ったりできると嬉しいと思い、lotlyが提供している可視化フレームワークであるDashを扱ってみる。[Dash Documentation & User Guide | Plotly](https://dash.plotly.com/)のチュートリアルを参考に進める。

# 実行環境

以下環境で実行した。
- Windows10 Pro
- Anaconda 4.9.2
- Python 3.7.6
- dash 1.19.0
- dash-core-components 1.15.0
- dash-html-components 1.1.2

Dashは以下コマンドでインストールした。

```python:install.py
conda install -c conda-forge dash
```

# データテーブルの可視化

チュートリアル[Dash Layout](https://dash.plotly.com/layout)に従って、以下コードを実行する。

```table.py
# Run this app with `python app.py` and
# visit http://127.0.0.1:8050/ in your web browser.

import dash
import dash_html_components as html
import pandas as pd

df = pd.read_csv('https://gist.githubusercontent.com/chriddyp/c78bf172206ce24f77d6363a2d754b59/raw/c353e8ef842413cae56ae3920b8fd78468aa4cb2/usa-agricultural-exports-2011.csv')


def generate_table(dataframe, max_rows=10):
    return html.Table([
        html.Thead(
            html.Tr([html.Th(col) for col in dataframe.columns])
        ),
        html.Tbody([
            html.Tr([
                html.Td(dataframe.iloc[i][col]) for col in dataframe.columns
            ]) for i in range(min(len(dataframe), max_rows))
        ])
    ])


external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div(children=[
    html.H4(children='US Agriculture Exports (2011)'),
    generate_table(df)
])

if __name__ == '__main__':
    app.run_server(debug=True)
```

[http://127.0.0.1:8050/](http://127.0.0.1:8050/)に接続すると、以下のようなテーブルが可視化される。

![table.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769545/3486d6b7-6d6a-60e3-f9e5-849b05e7c540.png)

上記をベースに、統計量の表示などが別タブで見られるように調査しながらカスタマイズしていく。データは[default of credit card clients Data Set](https://archive.ics.uci.edu/ml/datasets/default+of+credit+card+clients)を使用する。

# タブの追加

上記のような生データ自体を見るページとは別に基礎統計量などを見られるようにしたいと考えたため、別タブの追加を検討する。別タブの追加には、dash-core-components(以下dcc）にてdcc.Tabまたはdcc.Tabsが使用できる。dcc.Tabは個々のタブのスタイルと値を扱い、dcc.Tabsはdcc.Tabコンポーネントの集合を扱うとのこと。[dcc.Tab Reference](https://dash.plotly.com/dash-core-components/tab)、[Tabs Examples and Reference](https://dash.plotly.com/dash-core-components/tabs)を参考に単純にタブを追加してみる。以下に修正したコードを示す。使用しているデータには、[Rで基礎分析結果をCSV出力①全体編](https://qiita.com/honda28/items/6b378ec1c51366f3ab21)、[Rで基礎分析結果をCSV出力②量的変数編](https://qiita.com/honda28/items/4aa14ddcd0832946313f)で作成したCSVファイルを用いている。

```python:addTab.py
# Run this app with `python app.py` and
# visit http://127.0.0.1:8050/ in your web browser.

import dash
import dash_html_components as html
import dash_core_components as dcc
import pandas as pd

from dash.dependencies import Input, Output

df1 = pd.read_csv(
    "c:/***/default_of_credit_card_clients.csv", header=1)
df1.columns.values[0] = ''
df2 = pd.read_csv(
    "c:/***/summary.csv", header=0)
df2.columns.values[0] = ''
df3 = pd.read_csv(
    "c:/***/stats.csv", header=0)
df3.columns.values[0] = ''


def generate_table(dataframe, max_rows=10):
    return html.Table([
        html.Thead(
            html.Tr([html.Th(col) for col in dataframe.columns])
        ),
        html.Tbody([
            html.Tr([
                html.Td(dataframe.iloc[i][col]) for col in dataframe.columns
            ]) for i in range(min(len(dataframe), max_rows))
        ])
    ])


external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div([
    html.H4(children='default of credit card clients Data Set'),
    dcc.Tabs(id='tabs-example', value='tab-1', children=[
        dcc.Tab(label='raw data', value='tab-1'),
        dcc.Tab(label='number of missing values', value='tab-2'),
        dcc.Tab(label='stats', value='tab-3')
    ]),
    html.Div(id='tabs-example-content'),

])


@app.callback(Output('tabs-example-content', 'children'), Input('tabs-example', 'value'))
def render_content(tab):
    if tab == 'tab-1':
        return html.Div([
            generate_table(df1)
        ])
    elif tab == 'tab-2':
        return html.Div([
            generate_table(df2, max_rows=30)
        ])
    elif tab == 'tab-3':
        return html.Div([
            generate_table(df3, max_rows=20)
        ])


if __name__ == '__main__':
    app.run_server(debug=True)
```

結果は以下のようになる。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769545/cc936be8-f61b-0517-f23c-a9b7be7307cb.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769545/c4f0ea20-cfd4-406a-5aed-199f41f2b228.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769545/c54dd27e-fe49-00d2-3ac5-1383e0330a4d.png)

# おわりに

チュートリアルを参考に、別タブを追加してそれぞれのタブでデータを表示できた。次の記事では、図を作成し表示させてみる。