Plotly Dashとは
インストールや概念的な解説はこちらのリンクが詳しいです。
-
Plotly Dashで簡単に可視化ができるWebアプリを作る
https://qiita.com/driller/items/49e3b6084ec034353dc1 -
はんなりPythonの会#10でDashに関して発表してきた。
https://www.mazarimono.net/entry/2018/10/21/dash
Callback
Plotly Dashで入力を含むコンポーネントを作る際、少し戸惑うのがcallbackの部分だと思います。
しかし慣れてしまえば、すぐに使いこなすことができると思います。
ここでは、公式のサンプル https://dash.plot.ly/getting-started-part-2 をもとに、Input要素での入力内容を別の要素で表示させたいケースを考えます。
ソース
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
dcc.Input(id='input_id', value=None, type='text'),
html.Div(id='output_div')
])
@app.callback(
Output(component_id='output_div', component_property='children'),
[Input(component_id='input_id', component_property='value')]
)
def update_output_div(input_value):
if input_value:
return html.Div(className='output-area', children=[
html.Span(input_value)
])
else:
html.Div()
if __name__ == '__main__':
app.run_server(debug=True)
説明
>python app.py
で実行し、デフォルトのhttp://127.0.0.1:8050/ にアクセスすると下記の様な画面が表示されます。
まずapp.callbackデコレータ内の
[Input(component_id='input_id', component_property='value')]
に注目します。
これは、input_idというIDがある要素のvalue属性をみています。つまり
dcc.Input(id='input_id', value=None, type='text'),
のことで、ブラウザでは矢印先のinput要素をさしています。このvalueが変化した際に、Outputが発生します。
Output(component_id='output_div', component_property='children'),
アウトプットが描画される場所は、output_divというIDがある要素の子要素です。
つまり、
html.Div(id='output_div')
のことです。
if input_value:
return html.Div(className='output-area', children=[
html.Span(input_value)
])
なので、出力先のHTML要素は
div#output_div > div.output-area > span
という構造になっていると思います。
下記のスクリーンショットでわかるように、数字100がdiv#output_divの要素下のdiv.output-areaのspanに表示されていることがわかります。
component_idとcomponent_property
outputもinputもcomponent_idとcomponent_propertyが肝です。
どちらも必須で、これらがないと、どの要素を関連づけるのかわからないからです。
runする際にこの様なエラーが出て、IDが欠けていることを教えてくれます。
Attempting to assign a callback to the
component with the id "output_div" but no
components with id "output_div" exist in the
app's layout.
応用
ソースを変更して入力値が80以上であれば、合格
を出す様にしてみました。
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
dcc.Input(id='input_id', value=None, debounce=True, type='text'),
html.Div(id='output_div')
])
@app.callback(
Output(component_id='output_div', component_property='children'),
[Input(component_id='input_id', component_property='value')]
)
def update_output_div(input_value):
if input_value:
message = '不合格'
if input_value.isdigit() and int(input_value) >= 80:
message = '合格'
return html.Div(className='output-area', children=[
html.Span(message)
])
else:
html.Div()
if __name__ == '__main__':
app.run_server(debug=True)
参考サイト