いくつかのライブデータを監視し、プロットを操作するときにユーザーが独自の範囲を選択できるようにしたいと考えています。私はこの小さな例を作成し(チュートリアルからそれを取得しました)、問題は、プロットを更新するたびに、update_graph_live()
が新しいPlotly図を返すため、すべてがリセットされます。 (下の例を参照)
データのみを更新して、Figureがリロードされてデフォルトのビュー/設定にリセットされないようにすることは可能ですか?以前はd3.jsを使用していて、データをWebSocket経由で送信していたため、ブラウザーでデータをフィルター処理できました。でも、Dashで直接やりたいです。
import dash
from dash.dependencies import Output, Event
import dash_core_components as dcc
import dash_html_components as html
from random import random
import plotly
app = dash.Dash(__name__)
app.layout = html.Div(
html.Div([
html.H4('Example'),
dcc.Graph(id='live-update-graph'),
dcc.Interval(
id='interval-component',
interval=1*1000
)
])
)
@app.callback(Output('live-update-graph', 'figure'),
events=[Event('interval-component', 'interval')])
def update_graph_live():
fig = plotly.tools.make_subplots(rows=2, cols=1, vertical_spacing=0.2)
fig['layout']['margin'] = {
'l': 30, 'r': 10, 'b': 30, 't': 10
}
fig['layout']['legend'] = {'x': 0, 'y': 1, 'xanchor': 'left'}
fig.append_trace({
'x': [1, 2, 3, 4, 5],
'y': [random() for i in range(5)],
'name': 'Foo',
'mode': 'lines+markers',
'type': 'scatter'
}, 1, 1)
fig.append_trace({
'x': [1, 2, 3, 4, 5],
'y': [random() for i in range(5)],
'name': 'Bar',
'type': 'bar'
}, 2, 1)
return fig
if __name__ == '__main__':
app.run_server(debug=True)
animate=True
をdcc.Graph
に追加した場合、切り替えられたトレースと選択されたズーム/マーカー/何でも保持されますが、棒グラフでは機能しません(ただし、機能するはずですが https:// github .com/plotly/plotly.js/pull/114 )。さらに、完全なfigure
を返す代わりに、トレースを返すだけで済みます。
私が思いつくことができる最善の解決策は、それを2つのグラフに分割することですが、少なくとも望ましい機能のほとんどを得ることができます。
import dash
from dash.dependencies import Output, Event
import dash_core_components as dcc
import dash_html_components as html
from random import random
import plotly
app = dash.Dash(__name__)
app.layout = html.Div(
html.Div([
dcc.Graph(id='live-update-graph-scatter', animate=True),
dcc.Graph(id='live-update-graph-bar'),
dcc.Interval(
id='interval-component',
interval=1*1000
)
])
)
@app.callback(Output('live-update-graph-scatter', 'figure'),
events=[Event('interval-component', 'interval')])
def update_graph_scatter():
traces = list()
for t in range(2):
traces.append(plotly.graph_objs.Scatter(
x=[1, 2, 3, 4, 5],
y=[(t + 1) * random() for i in range(5)],
name='Scatter {}'.format(t),
mode= 'lines+markers'
))
return {'data': traces}
@app.callback(Output('live-update-graph-bar', 'figure'),
events=[Event('interval-component', 'interval')])
def update_graph_bar():
traces = list()
for t in range(2):
traces.append(plotly.graph_objs.Bar(
x=[1, 2, 3, 4, 5],
y=[(t + 1) * random() for i in range(5)],
name='Bar {}'.format(t)
))
layout = plotly.graph_objs.Layout(
barmode='group'
)
return {'data': traces, 'layout': layout}
if __name__ == '__main__':
app.run_server(debug=True)
バー、ボックス、ヒストグラムプロットの場合、使用しないでくださいanimate=True
そうでない場合、プロットはプロット領域外になります。また、EventはDash Plotlyによって非推奨になりました。代わりにInputを使用してください。
import dash
from dash.dependencies import Output,Input
import dash_core_components as dcc
import dash_html_components as html
from random import random
import plotly
app = dash.Dash(__name__)
app.layout = html.Div(
html.Div([
dcc.Graph(id='live-update-graph-scatter', animate=True),
dcc.Graph(id='live-update-graph-bar'),
dcc.Interval(
id='interval-component',
interval=1*1000
)
])
)
@app.callback(Output('live-update-graph-scatter', 'figure'),
[Input('interval-component', 'interval')])
def update_graph_scatter():
traces = list()
for t in range(2):
traces.append(plotly.graph_objs.Scatter(
x=[1, 2, 3, 4, 5],
y=[(t + 1) * random() for i in range(5)],
name='Scatter {}'.format(t),
mode= 'lines+markers'
))
return {'data': traces}
@app.callback(Output('live-update-graph-bar', 'figure'),
[Input('interval-component', 'interval')])
def update_graph_bar():
traces = list()
for t in range(2):
traces.append(plotly.graph_objs.Bar(
x=[1, 2, 3, 4, 5],
y=[(t + 1) * random() for i in range(5)],
name='Bar {}'.format(t)
))
layout = plotly.graph_objs.Layout(
barmode='group'
)
return {'data': traces, 'layout': layout}
if __name__ == '__main__':
app.run_server(debug=True)