こんにちは!データサイエンティストのウマたん(@statistics1012)です。
この記事ではDashとPlotlyを使ってデータ可視化Webアプリを構築する方法を見ていきます。
Pythonでデータ可視化Webアプリを作るライブラリとしては他にもStreamlitというライブラリがありますが、Dashも非常に便利です。
DashとStreamlitの違いも見ながらDashの使い方を詳しく見ていきましょう!
目次
Dashで出来ることとPlotlyとの関係について
DashはPlotly社によって提供されているライブラリでデータ可視化とインタラクティブなWebアプリを容易に構築できるツールです。
PlotlyとDashについて具体的には以下です。
- Plotly:最初はデータ可視化ライブラリとして登場し、現在もJupyter labや他のデータ分析ツールで使われるインタラクティブなグラフライブラリ。
- Dash:Plotly社がPlotlyのグラフを利用して、よりインタラクティブなデータアプリケーションやダッシュボードをPythonで簡単に作成できるように設計したフレームワーク
Plotlyの使い方については以下の記事で詳しく解説していますので合わせてチェックしてみてください。
PlotlyとDashの違いが分かったところで、Dashで出来ることを簡単にまとめていきましょう!
- Dashを使うことで簡単にPlotlyのパーツを組み込むことができ、インタラクティブにユーザーが入力した情報をもとにグラフの描画を変化させるダッシュボードを作成可能
- ドロップダウンや入力ボックスなどのコンポーネントも容易に追加することができ、UIもHTML/CSSの知識を使って作り込むことが可能
- データをリアルタイムで取得し、定期的にグラフを更新することも可能
このように非常に便利なライブラリがこのDashなのです!!
ちなみに、同じようなことが同様にPythonのWebアプリフレームワークであるStreamlitでも実現できますが、Streamlitよりも複雑な処理を構築することができUIも詳細まで作り込むことが可能です。
違いをまとめると以下のようになります。
Dash | Streamlit |
---|---|
ターゲット | |
エンタープライズ、複雑なダッシュボード | データサイエンティスト、分析者 |
レイアウトの柔軟性 | |
高いカスタマイズ性 | コードの順序で表示、シンプル |
コールバック機能 | |
入力と出力を関数で管理 | アプリ全体の再実行 |
デプロイ | |
Dash Enterprise、Webサーバーへの対応 | Streamlit Cloud、GitHubと連携可能 |
学習コスト | |
中程度 | 低い、簡単 |
適用例 | |
ビジネス向けダッシュボード、複雑なアプリ | MLデモ、データ分析レポート、プロトタイプ |
Streamlitに関して詳しくは以下の記事でまとめていますのでチェックしてみてください!
Dashで可視化Webアプリを作っていこう!
それでは、ここからDashを実際に使って可視化Webアプリを作っていきます!
以下の公式チュートリアルを参考に見ていきましょう!
Hello Worldの表示
まずは定番のHello Worldを表示してみましょう!以下のようにコードを記載してください。
from dash import Dash, html
app = Dash()
app.layout = [html.Div(children='Hello World')]
if __name__ == '__main__':
app.run(debug=True)
これを実行すると真っ白な画面上にHello World!と表示されるはずです。
それでは具体的にどんな処理をしているのか追って見ていきます。
まず、アプリを初期化するために「app = Dash()
」と記載しています。必ずDashでWebアプリを作る際は必ず初めに記載してください。
続いて「app.layout = [html.Div(children=’Hello World’)]」と記載しています。この部分でHello Worldを表示しています。
html.DivでHTMLのdivタグを生成しており、childrenでその配下にコンポーネントを配置することができます。
今回はテキストを記載しているので、そのままdivタグ内にテキストが表示されるような形になります。
続いて以下のパートは、アプリを立ち上げるためのコマンドです。
if __name__ == '__main__':
app.run(debug=True)
Dashを使ってアプリを構築する際は必ず記載しましょう。
データの連携と可視化
続いてデータの連携と可視化をしてみましょう!
全コードは以下のようになります。
# Import packages
from dash import Dash, html, dash_table, dcc
import pandas as pd
import plotly.express as px
# Incorporate data
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv')
# Initialize the app
app = Dash()
# App layout
app.layout = [
html.Div(children='My First App with Data and a Graph'),
dash_table.DataTable(data=df.to_dict('records'), page_size=10),
dcc.Graph(figure=px.histogram(df, x='continent', y='lifeExp', histfunc='avg'))
]
# Run the app
if __name__ == '__main__':
app.run(debug=True)
結果は以下のようになります。
ちゃんとデータを連携後にテーブルを表示してグラフを可視化できていることが分かりますね!
それでは具体的にどんな処理なのか追ってみていきましょう!
まずは以下の処理でplotly社が用意しているCSVデータを取得しています。
# Incorporate data
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv')
これは各国の小麦の生産量や寿命などが格納されたデータです。
続いて以下の処理でWebアプリ上に表やグラフを表示しています。
# App layout
app.layout = [
html.Div(children='My First App with Data and a Graph'),
dash_table.DataTable(data=df.to_dict('records'), page_size=10),
dcc.Graph(figure=px.histogram(df, x='continent', y='lifeExp', histfunc='avg'))
]
まず、先ほどの”Hello World”で学んだようにdivタグでテキストを表示しています。
続いて、テーブルを表示しています。この際、引数のdataには辞書型でデータを渡す必要がありますので、データフレームをレコードごとに辞書形式にして渡しています。
またpage_sizeに10を指定することで10レコードごとに表示して見やすくしています。
最後にdcc.Graphを使ってplotlyのグラフを表示しています。
非常に簡単にWebアプリを作成できることがわかると思います!
インタラクティブなWebアプリの作成
続いてユーザーが入力したインプットを基にグラフを変えるインタラクティブなWebアプリを作成してみましょう!
ここではコールバック関数というものを作って処理を制御していきます。
ユーザーのインプットを引数にして特定の処理を行う関数です。
それではコードを見ていきましょう!全コードは以下のようになります。
# Import packages
from dash import Dash, html, dash_table, dcc, callback, Output, Input
import pandas as pd
import plotly.express as px
# Incorporate data
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv')
# Initialize the app
app = Dash()
# App layout
app.layout = [
html.Div(children='My First App with Data, Graph, and Controls'),
html.Hr(),
dcc.RadioItems(options=['pop', 'lifeExp', 'gdpPercap'], value='lifeExp', id='controls-and-radio-item'),
dash_table.DataTable(data=df.to_dict('records'), page_size=6),
dcc.Graph(figure={}, id='controls-and-graph')
]
# Add controls to build the interaction
@callback(
Output(component_id='controls-and-graph', component_property='figure'),
Input(component_id='controls-and-radio-item', component_property='value')
)
def update_graph(col_chosen):
fig = px.histogram(df, x='continent', y=col_chosen, histfunc='avg')
return fig
# Run the app
if __name__ == '__main__':
app.run(debug=True)
結果は以下のようになり、ラジオボタンをポチポチするとそれに合わせてグラフが変化するようになってます。
ちょっと複雑な処理になってきましたね。それでは順に追って見ていきましょう!
まずlayoutの部分を見ていきましょう!
# App layout
app.layout = [
html.Div(children='My First App with Data, Graph, and Controls'),
html.Hr(),
dcc.RadioItems(options=['pop', 'lifeExp', 'gdpPercap'], value='lifeExp', id='controls-and-radio-item'),
dash_table.DataTable(data=df.to_dict('records'), page_size=6),
dcc.Graph(figure={}, id='controls-and-graph')
]
タイトルを表示した後にhtml.Hr()で区切り線を入れています。
その後「dcc.RadioItems(options=[‘pop’, ‘lifeExp’, ‘gdpPercap’], value=’lifeExp’, id=’controls-and-radio-item’)」の箇所でラジオボタンを描画しています。
optionsの引数で3つの選択を与えていて、初期値はlifeExpに設定しています。
またidを与えることで、ラジオボタンで選択した値をその後のコールバック関数に渡せるようにしています。
その後の例によってテーブルを描画し、最後に「dcc.Graph(figure={}, id=’controls-and-graph’)」の部分で描画をしていくのですが、figureの部分は空になっています。
この後の関数部分の返り値がこのfigureに入るようになります。
それではコールバック関数の部分を見ていきましょう!
# Add controls to build the interaction
@callback(
Output(component_id='controls-and-graph', component_property='figure'),
Input(component_id='controls-and-radio-item', component_property='value')
)
def update_graph(col_chosen):
fig = px.histogram(df, x='continent', y=col_chosen, histfunc='avg')
return fig
@デコレータを使ってInputの値とOutputの値を制御しています。
Inputのcomponent_idはラジオボタンのcomponent_idと一致するのでラジオボタンのvalueがupdate_graph関数のcol_shosen引数としてインプットされます。
その後、plotlyでヒストグラムを描画しfigを返り値として返しています。
Outputのcomponent_idはdcc.Graphのcomponent_idと一致するのでその返り値はdcc.Graphのfigureに入ります。
これにより、ユーザーのインプットを基にグラフが変化するのです。
HTMLとCSSで装飾
続いてHTMLとCSSでUIを修正してみましょう!
まずコード全体を見ていきます。
# Import packages
from dash import Dash, html, dash_table, dcc, callback, Output, Input
import pandas as pd
import plotly.express as px
# Incorporate data
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv"
)
# Initialize the app - incorporate css
external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
app = Dash(external_stylesheets=external_stylesheets)
# App layout
app.layout = [
html.Div(
className="row",
children="My First App with Data, Graph, and Controls",
style={"textAlign": "center", "color": "blue", "fontSize": 30},
),
html.Div(
className="row",
children=[
dcc.RadioItems(
options=["pop", "lifeExp", "gdpPercap"],
value="lifeExp",
inline=True,
id="my-radio-buttons-final",
)
],
),
html.Div(
className="row",
children=[
html.Div(
className="six columns",
children=[
dash_table.DataTable(
data=df.to_dict("records"),
page_size=11,
style_table={"overflowX": "auto"},
)
],
),
html.Div(
className="six columns",
children=[dcc.Graph(figure={}, id="histo-chart-final")],
),
],
),
]
# Add controls to build the interaction
@callback(
Output(component_id="histo-chart-final", component_property="figure"),
Input(component_id="my-radio-buttons-final", component_property="value"),
)
def update_graph(col_chosen):
fig = px.histogram(df, x="continent", y=col_chosen, histfunc="avg")
return fig
# Run the app
if __name__ == "__main__":
app.run(debug=True)
結果は以下のようになりました。
基本的にはコードの流れは今までと同じなのですが、UIが変わっているのが分かると思います。
まず以下の部分でexternal_stylesheets
にCSSスタイルシートのURLを指定し、アプリケーションに読み込ませています。
# Initialize the app - incorporate css
external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
app = Dash(external_stylesheets=external_stylesheets)
そして今までシンプルだったタイトルに対して以下のようにクラスネームとスタイルを施しています。
html.Div(
className="row",
children="My First App with Data, Graph, and Controls",
style={"textAlign": "center", "color": "blue", "fontSize": 30},
),
クラスネームは特に現状必要ではないのですが、公式のチュートリアルに付いているのでそのまま付けておきましょう。
スタイルはテキストをセンターにして色を青にしてフォントサイズを30pxにしています。
続いてはラジオボタン。
html.Div(
className="row",
children=[
dcc.RadioItems(
options=["pop", "lifeExp", "gdpPercap"],
value="lifeExp",
inline=True,
id="my-radio-buttons-final",
)
],
),
基本はこれまでと変わっていないのですが、inline=Trueにすることでラジオボタンが横並びになってます。
続いてテーブルとグラフ。
html.Div(
className="row",
children=[
html.Div(
className="six columns",
children=[
dash_table.DataTable(
data=df.to_dict("records"),
page_size=11,
style_table={"overflowX": "auto"},
)
],
),
html.Div(
className="six columns",
children=[dcc.Graph(figure={}, id="histo-chart-final")],
),
],
),
ここではクラスネームにsix columnsを指定することで2つの要素を横並びで表示しています。
これはグリッド12個に対して最初の6グリッドと後の6グリッドに分けて表示する方法です。
「style_table={“overflowX”: “auto”}」はテーブルが列幅を超える時にスクロールできるようにしていますが、現状のデータではそれほど意味はありません。
こんな感じでPythonコードの中にHTMLとCSSを埋め込むことで様々なUI修正が簡単にできるのです。
こういった意味でStreamlitよりも細かい微修正が可能なライブラリになってます。
株価を取得してそれを可視化するWebアプリを作ってみよう!
それでは最後に応用編として株価を取得して可視化するWebアプリを作っていきましょう!
コード全体は以下のようになります。
# Import packages
from dash import Dash, html, dash_table, dcc, callback, Output, Input
import pandas as pd
import plotly.express as px
import yfinance as yf # Yahoo Financeから株価データを取得するライブラリ
# Load stock data (S&P 500の主要企業)
symbols = ["AAPL", "MSFT", "GOOGL", "AMZN", "TSLA"]
stock_data = {symbol: yf.download(symbol, period="1y", interval="1mo") for symbol in symbols}
# Initialize the app with external CSS
external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
app = Dash(external_stylesheets=external_stylesheets)
# App layout
app.layout = html.Div([
html.H1("Stock Price Dashboard", style={"textAlign": "center", "color": "navy"}),
html.Div([
html.Label("Select Stock:"),
dcc.Dropdown(
id="stock-dropdown",
options=[{"label": symbol, "value": symbol} for symbol in symbols],
value="AAPL"
)
], style={"width": "50%", "margin": "0 auto", "textAlign": "center"}),
# グラフとテーブルを横並びに配置
html.Div([
# 左側のグラフ
html.Div([
html.H2("Stock Price", style={"textAlign": "center"}),
dcc.Graph(id="stock-graph")
], style={"width": "50%", "padding": "10px"}),
# 右側のテーブル
html.Div([
html.H2("Stock Data Table", style={"textAlign": "center"}),
dash_table.DataTable(id="stock-table", page_size=5, style_table={"overflowX": "auto"})
], style={"width": "50%", "padding": "10px"})
], style={"display": "flex", "justifyContent": "center"}),
])
# Callback function to update stock graph and data table based on selected stock
@callback(
[Output("stock-graph", "figure"),
Output("stock-table", "data")],
[Input("stock-dropdown", "value")]
)
def update_stock_data(symbol):
# 選択した銘柄の株価データを取得し、リセットして使いやすくする
data = stock_data[symbol].reset_index()
# 折れ線グラフを生成
fig = px.line(data, x="Date", y="Close", title=f"{symbol} Stock Price Over Time")
# データテーブル用のデータを準備
table_data = data[["Date", "Open", "High", "Low", "Close", "Volume"]].to_dict("records")
return fig, table_data
# Run the app
if __name__ == "__main__":
app.run(debug=True)
結果は以下のようになりました!
銘柄をドロップダウンで選択できるようになっており、選択した銘柄に応じて左のグラフと右のテーブルが変化するようになっています。
株価取得に関しては以下のコードで処理しています。
yf.download(symbol, period="1y", interval="1mo")
yfinanceというライブラリを使うだけで誰でも簡単に株価を取得できるんです!
Pythonにおける株価に関しては以下の記事で解説していますので合わせてチェックしてみてください!
それ以外は基本的にこれまで解説してきたことの組み合わせなので大丈夫なはず!
ぜひ理解を深めて自分だけのWebアプリを作っていきましょう!
ちなみにDashのリファレンスとしては以下をまず読んでみてください。
・Dash Example Index:Dashを使った様々な可視化の例が載っている
・Dash 公式リファレンス:公式リファレンス
・Dash in 20 Minutes Tutorial:公式リファレンスのチュートリアル
Dash&Plotly まとめ
ということでここまででDashとPlotlyを使って簡単にWebアプリを構築する方法を見てきました!
非常に便利なのでぜひ使えるようになっておいてください!
さらに詳しくAIやデータサイエンスの勉強がしたい!という方は当サイト「スタビジ」が提供するスタビジアカデミーというサービスで体系的に学ぶことが可能ですので是非参考にしてみてください!
AIデータサイエンス特化スクール「スタアカ」
【価格】 | ライトプラン:1280円/月 プレミアムプラン:149,800円 |
---|---|
【オススメ度】 | |
【サポート体制】 | |
【受講形式】 | オンライン形式 |
【学習範囲】 | データサイエンスを網羅的に学ぶ 実践的なビジネスフレームワークを学ぶ SQLとPythonを組み合わせて実データを使った様々なワークを行う マーケティングの実行プラン策定 マーケティングとデータ分析の掛け合わせで集客マネタイズ |
データサイエンティストとしての自分の経験をふまえてエッセンスを詰め込んだのがこちらのスタビジアカデミー、略して「スタアカ」!!
当メディアが運営するスクールです。
24時間以内の質問対応と現役データサイエンティストによる複数回のメンタリングを実施します!
カリキュラム自体は、他のスクールと比較して圧倒的に良い自信があるのでぜひ受講してみてください!
他のスクールのカリキュラムはPythonでの機械学習実装だけに焦点が当たっているものが多く、実務に即した内容になっていないものが多いです。
そんな課題感に対して、実務で使うことの多いSQLや機械学習のビジネス導入プロセスの理解なども合わせて学べるボリューム満点のコースになっています!
Pythonが初めての人でも学べるようなカリキュラムしておりますので是非チェックしてみてください!
ウォルマートのデータを使って商品の予測分析をしたり、実務で使うことの多いGoogleプロダクトのBigQueryを使って投球分析をしたり、データサイエンティストに必要なビジネス・マーケティングの基礎を学んでマーケティングプランを作ってもらったり・Webサイト構築してデータ基盤構築してWebマーケ×データ分析実践してもらったりする盛りだくさんの内容になってます!
・BigQuery上でSQL、Google Colab上でPythonを使い野球の投球分析
・世界最大手小売企業のウォルマートの実データを用いた需要予測
・ビジネス・マーケティングの基礎を学んで実際の企業を題材にしたマーケティングプランの策定
・Webサイト構築してデータ基盤構築してWebマーケ×データ分析実践して稼ぐ