Dashを使うとweb上でインタラクティブにデータを可視化するためのダッシュボードを作成できます。コードはPythonベースで書くことができ、htmlやCSSの知識はあまり必要ありません(基本的なことは分かっていた方が良さそうですが)。数回に分けて量的・質的データを含むkaggleデータを可視化するためのダッシュボードを作成するまでの過程をまとめました。
最終的なコードはこちらのGitHubリポジトリに公開しています。
作成するダッシュボード
完成図
以下のようにSidebarで特徴や相関関係などを確認したいカテゴリカル変数・連続変数をそれぞれ選択し、右側に選択した変数の分布や相関行列のヒートマップが出力されるダッシュボードを作っていきます。
ダッシュボードを作成する手順は以下の5つに分けられます。
- レイアウトの設定
- コンポーネントの配置
- スタイルの設定
- Plotlyでグラフを作成
- インタラクティブにグラフが変化するように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)
最後にもう一度実行します。
次の記事ではこの状態からコンポーネントの設定やスタイルの整備をしていきます。
コメント