【问题标题】:Access selectedData from html.Div children从 html.Div 子项访问 selectedData
【发布时间】:2019-08-20 19:17:23
【问题描述】:

为了避免在没有可绘制的信息时显示空的图形轴,我将 dcc.Graph 返回对象替换为 html.Div(),它会获得 [][dcc.Graph(...)] 的输出回调。

现在,我想对 selectedData 启用其他操作(如果 Div 有子图)。以前我可以这样做:

@app.callback(Output('something', 'children'), 
              [Input('graph', 'selectedData')])
def do_stuff(selectedData):
    pass

现在我已经将布局项从dcc.Graph(...) 更改为html.Div([dcc.Graph(...)]),我不知道如何访问selectedData

@app.callback(Output('something', 'children'), 
              [Input('graph_div', 'children')])
def do_stuff(children):
    if len(children) > 0:
        graph = children[0]
    # wheres the selectedData now?

或者,如果有办法将输入id 直接获取到嵌套的dcc.Graphid 可能会更容易?当我尝试此操作时,我收到一条错误消息,提示应用程序的布局中不存在具有此 ID 的组件。

【问题讨论】:

    标签: graph mouseevent plotly-dash plotly-python


    【解决方案1】:

    对于每个组件,应该可以在 Dash 中注册一个回调,

    这是一个简单的示例,它复制了您正在尝试做的事情,

    import dash
    import dash_core_components as dcc
    from dash.dependencies import Input, Output
    
    app = dash.Dash(__name__)
    
    app.layout = html.Div([
        html.Div(id="graph-div",
            children=[
                dcc.Graph(
                    id='graph',
                    figure={
                        'data': [
                            {
                                'x': [1, 2, 3, 4],
                                'y': [4, 1, 3, 5],
                                'text': ['a', 'b', 'c', 'd'],
                                'customdata': ['c.a', 'c.b', 'c.c', 'c.d'],
                                'name': 'Trace 1',
                                'mode': 'markers',
                                'marker': {'size': 12}
                            },
                            {
                                'x': [1, 2, 3, 4],
                                'y': [9, 4, 1, 4],
                                'text': ['w', 'x', 'y', 'z'],
                                'customdata': ['c.w', 'c.x', 'c.y', 'c.z'],
                                'name': 'Trace 2',
                                'mode': 'markers',
                                'marker': {'size': 12}
                            }
                        ],
                        'layout': {
                            'clickmode': 'event+select'
                        }
                    }
                ),
            ]
        ),
        html.Div(id="output")
    ])
    
    @app.callback(Output('output', 'children'), 
                  [Input('graph', 'selectedData')])
    def do_stuff(selectedData):
        print(selectedData)
    
    if __name__ == '__main__':
        app.run_server(debug=True)
    
    

    如果你可以发布一个简单的可重新创建的代码,它会更容易调试。

    更新:

    如果您正在尝试动态加载组件,您可能会遇到上述问题,

    https://community.plot.ly/t/dcc-tabs-filling-tabs-with-dynamic-content-how-to-organize-the-callbacks/6377/2

    解决此问题的一种简单方法是设置此应用配置, app.config['suppress_callback_exceptions']=True

    这是工作示例,

    import dash
    import dash_core_components as dcc
    import dash_html_components as html
    from dash.dependencies import Input, Output
    import pandas as pd
    
    
    #
    #https://stackoverflow.com/questions/57580240/access-selecteddata-from-html-div-children
    #
    
    
    graph_layout = dcc.Graph(
                    id='graph',
                    figure={
                        'data': [
                            {
                                'x': [1, 2, 3, 4],
                                'y': [4, 1, 3, 5],
                                'text': ['a', 'b', 'c', 'd'],
                                'customdata': ['c.a', 'c.b', 'c.c', 'c.d'],
                                'name': 'Trace 1',
                                'mode': 'markers',
                                'marker': {'size': 12}
                            },
                            {
                                'x': [1, 2, 3, 4],
                                'y': [9, 4, 1, 4],
                                'text': ['w', 'x', 'y', 'z'],
                                'customdata': ['c.w', 'c.x', 'c.y', 'c.z'],
                                'name': 'Trace 2',
                                'mode': 'markers',
                                'marker': {'size': 12}
                            }
                        ],
                        'layout': {
                            'clickmode': 'event+select'
                        }
                    }
                )
    app = dash.Dash(__name__)
    
    app.config['suppress_callback_exceptions']=True 
    
    app.layout = html.Div([
        dcc.Dropdown(id="toggle-graph",
            options=[
                {'label': 'on', 'value': 'on'},
                {'label': 'off', 'value': 'off'},
            ],
            value='on'
        ) , 
        html.Div(id="graph-div",
            children=[
    
            ]
        ),
        html.Div(id="output")
    ])
    
    
    @app.callback(Output('graph-div', 'children'), 
                  [Input('toggle-graph', 'value')])
    def do_stuff(value):
        if(value == 'on'):
            return graph_layout
        else:
            return []
    
    
    @app.callback(Output('output', 'children'), 
                  [Input('graph', 'selectedData')])
    def do_stuff(selectedData):
        print(selectedData)
    
    if __name__ == '__main__':
        app.run_server(debug=True)
    
    

    【讨论】:

    • 谢谢。我希望有条件地显示整个图形窗格,例如,如果选中了一个复选框。是否可以有一个条件布局对象用作回调的输入?
    【解决方案2】:

    看起来我需要的是一种切换图形显示的方法,而不是有条件地返回整个图形对象:

    @app.callback(Output('graph', 'style'), [Input('drop-down', 'value')])
    def toggle_container(dropdown_value):
        if something
            return {'display': 'none'}
        else:
            return {'display': 'block'}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-08
      • 1970-01-01
      • 1970-01-01
      • 2010-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多