【Python】DashとPlotlyでダッシュボードを作成する手順(1.レイアウト編)

Dash

Dashを使うとweb上でインタラクティブにデータを可視化するためのダッシュボードを作成できます。コードはPythonベースで書くことができ、htmlやCSSの知識はあまり必要ありません(基本的なことは分かっていた方が良さそうですが)。数回に分けて量的・質的データを含むkaggleデータを可視化するためのダッシュボードを作成するまでの過程をまとめました。

最終的なコードはこちらのGitHubリポジトリに公開しています。

作成するダッシュボード

完成図

以下のようにSidebarで特徴や相関関係などを確認したいカテゴリカル変数・連続変数をそれぞれ選択し、右側に選択した変数の分布や相関行列のヒートマップが出力されるダッシュボードを作っていきます。

ダッシュボードを作成する手順は以下の5つに分けられます。

  1. レイアウトの設定
  2. コンポーネントの配置
  3. スタイルの設定
  4. Plotlyでグラフを作成
  5. インタラクティブにグラフが変化するようにCallbackを設定

本記事では手順1のレイアウトの設定方法をまとめます。手順2.3はコンポーネント、スタイル編を手順4.5はコールバック編をご覧ください。

データ

上記のダッシュボードではkaggleのtabular playground series Mar 2021のデータの一部を使用しています。このデータは下表の通りサンプルidと19個のカテゴリカル変数(cat0 ~ cat18)と11個の連続変数(cont0 ~ cont10)、そして2値(0,1)のターゲット変数が含まれます。

SidebarとContentに分割する

bootstrapはウェブサイトやwebアプリケーションを作成するためのフレームワークです。dashでもdash bootstrap componentsをインポートすることで、このフレームワークを使うことができます。まずは必要なモジュールをインポートします。次にDashインスタンスを生成し、bootstrapのstylesheetsを読み込みます。dbc.themesの後ろを変更すると、配色やフォント、コンポーネントの見え方など全体のテーマを変えることができますが、ここではFLATLYに選びました。

import dash
import dash_bootstrap_components as dbc
import dash_html_components as html

app = dash.Dash(external_stylesheets=[dbc.themes.FLATLY])

bootstrapには画面を行と列に分割するgrid systemがあり、dbc.Containerの中にdbc.Rowとdbc.Colを組み合わせることで全体のレイアウトを作っていきます。今回は変数を選択するSidebarとグラフやヒートマップを表示するContentに分かれますが、これらを画面全体を1:3に分割するようにレイアウトします。

app.layout = dbc.Container(
    [
        dbc.Row(
            [
                dbc.Col(sidebar, width=3, className='bg-light'),
                dbc.Col(content, width=9)
                ],
            style={"height": "100vh"}
            ),
        ],
    fluid=True
    )

grid systemでは画面を12個の列に分けるので、dbc.Colのwidthを3と9にすることで1:3に分割することができます。classNameではbootstrapの様々な属性を設定することができます。背景色を設定するために’bg-‘を使っていて、ここではテーマがFLATLYなのでbg-lightで薄いグレーになります。他の色は次の通りで、例えばbg-infoと設定すると青色になります。FLATLYの詳細はこちらをご覧ください。

style={“height”: “100vh”}のvhはviewport heightの略でスクリーン高さの100%に設定するという意味です。dbc.Containerはデフォルトで余白が設定されているので、上下左右やSidebarとContentの間に意図せぬ余白が出ないようにfluid=Trueと設定します。

上記のsidebar変数とcontent変数は一旦以下のように1文を表示するように設定します。

sidebar = html.Div(
    [
        html.P('Sidebar')
        ]
)

content = html.Div(
    [
        html.P('Content')
    ]
)

これで一度実行します。

if __name__ == "__main__":
    app.run_server(debug=True, port=1234)

するとhttp://127.0.0.1:1234/に以下のような画面が立ち上がります。

sidebarは薄いグレーになり、それぞれ設定どおりに表示させることができました。

レイアウトを整える

次にSidebarのレイアウトを整えます。SidebarはSettingsという見出し、カテゴリカル変数と連続変数を選択する箇所、ターゲット変数の円グラフを表示させる箇所に分かれます。行の分割はdbc.Rowで設定し、それぞれの高さをスクリーンを1:10:9になるようにvhを指定して分割します。

先ほどのsidebar変数を以下のように書き換えます。

sidebar = html.Div(
    [
        dbc.Row(
            [
                html.P('Settings')
                ],
            style={"height": "5vh"}, className='bg-primary text-white'
            ),
        dbc.Row(
            [
                html.P('Categorical and Continuous Variables')
                ],
            style={"height": "50vh"}, className='bg-secondary text-white'
            ),
        dbc.Row(
            [
                html.P('Target Variables')
                ],
            style={"height": "45vh"}, className='bg-dark text-white'
            )
        ]
    )

ここでは分割が分かりやすくなるように、便宜的にclassNameで背景色を指定しています。

次にContentのレイアウトを整えます。上段はカテゴリカル変数のグラフ部分と連続変数のグラフ部分に2分割する必要があるのでSidebarとContentを分割した時と同じようにdbc.Colを使います。今回は均等に分割するのでwidthは指定しません。

先ほどのcontent変数を以下のように書き換えます。

content = html.Div(
    [
        dbc.Row(
            [
                dbc.Col(
                    [
                        html.P('Distribution of Categorical Variable'),
                        ],
                    className='bg-white'
                    ),
                dbc.Col(
                    [
                        html.P('Distribution of Continuous Variable')
                    ],
                    className='bg-dark text-white'
                    )
            ],
            style={"height": "50vh"}),
        dbc.Row(
            [
                dbc.Col(
                    [
                        html.P('Correlation Matrix Heatmap')
                    ],
                    className='bg-light'
                    )
            ],
            style={"height": "50vh"}
            )
        ]
    )

もう1度実行します。

完成図と同じように分割することができました。

コード全体は次の通りになります。dbc.Containerの中でstyle={“height”: “100vh”}と設定していましたが、各パーツでvhを設定して不要になったので削除しています。また便宜的に設定していた背景色の設定も削除しました。

import dash
import dash_bootstrap_components as dbc
import dash_html_components as html


app = dash.Dash(external_stylesheets=[dbc.themes.FLATLY])

sidebar = html.Div(
    [
        dbc.Row(
            [
                html.P('Settings')
                ],
            style={"height": "5vh"}
            ),
        dbc.Row(
            [
                html.P('Categorical and Continuous Variables')
                ],
            style={"height": "50vh"}
            ),
        dbc.Row(
            [
                html.P('Target Variables')
                ],
            style={"height": "45vh"}
            )
        ]
    )

content = html.Div(
    [
        dbc.Row(
            [
                dbc.Col(
                    [
                        html.P('Distribution of Categorical Variable'),
                        ]),
                dbc.Col(
                    [
                        html.P('Distribution of Continuous Variable')
                    ])
            ],
            style={"height": "50vh"}),
        dbc.Row(
            [
                dbc.Col(
                    [
                        html.P('Correlation Matrix Heatmap')
                    ])
            ],
            style={"height": "50vh"}
            )
        ]
    )

app.layout = dbc.Container(
    [
        dbc.Row(
            [
                dbc.Col(sidebar, width=3, className='bg-light'),
                dbc.Col(content, width=9)
                ]
            ),
        ],
    fluid=True
    )


if __name__ == "__main__":
    app.run_server(debug=True, port=1234)

最後にもう一度実行します。

次の記事ではこの状態からコンポーネントの設定やスタイルの整備をしていきます。

コメント