20

我想监控一些实时数据并允许用户在与绘图交互时选择自己的范围。我创建了这个小例子(从教程中得到),问题是,每次我更新情节时,一切都会重置,因为update_graph_live()返回一个新的情节图。(见下面的例子)

是否可以仅更新数据,因此不会重新加载图形并重置为默认视图/设置?我之前使用 d3.js 并通过 websockets 发送数据,所以我可以在浏览器中过滤数据。但我想直接用 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)
4

2 回答 2

14

如果您添加animate=Truedcc.Graph切换的轨迹并选择缩放/标记/保留的任何内容,但这不适用于条形图(尽管它应该有效:https ://github.com/plotly/plotly.js/pull/1143 )。此外,figure您不需要返回完整的,而是只需要返回跟踪。

我能想出的最佳解决方案是将它分成两个图表,但您至少会获得大部分所需的功能。

在此处输入图像描述

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)
于 2017-09-07T10:47:07.677 回答
4

对于Bar, Box 和 Histogram plot,您不应该使用 animate=True,否则绘图将超出绘图区域。此外,Dash Plotly 已弃用 Event,请改用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)
于 2019-02-28T18:07:18.673 回答