【问题标题】:Zoom on both graphs via highlighting selection in Dash通过在 Dash 中突出显示选择来放大两个图表
【发布时间】:2020-01-06 03:41:09
【问题描述】:

我正在尝试使这两个图表具有响应性,以便如果我突出显示一个选择并放大其中一个,另一个图表会在同一日期放大。

例如,在我发布的第一张图片中,如果我在 1 月份放大一个图表,我希望另一个图表也在同一日期范围内放大。

您可以在我附上的图片中看到我想要做什么。

谁能帮帮我?

import dash
import dash_core_components as dcc
import dash_html_components as html
import ssl
import pandas as pd

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

ssl._create_default_https_context = ssl._create_unverified_context


df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv")

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

colors = {
    'background': '#111111',
    'text': '#7FDBFF'
}

app.layout = html.Div(style={'backgroundColor': colors['background']}, children=[
    html.H1(
        children='graph1',
        style={
            'textAlign': 'center',
            'color': colors['text']
        }
    ),

    html.Div(children='Displaying Apple High and Low.', style={
        'textAlign': 'center',
        'color': colors['text']
    }),

    dcc.Graph(
        id='example-graph-2',
        figure={
            'data': [
                {'y': df['AAPL.Open'], 'x': df['Date'], 'type': 'line', 'name': 'Activity'},
                {'y': df['AAPL.High'], 'x': df['Date'], 'type': 'line', 'name': 'Baseline'},
            ],
            'layout': {
                'plot_bgcolor': colors['background'],
                'paper_bgcolor': colors['background'],
                'font': {
                    'color': colors['text']
                }
            }
        }
    ),

    html.Div(children='Second Graph (Volume).', style={
        'textAlign': 'center',
        'color': colors['text']
    }),

    dcc.Graph(
        id='graph2',
        figure={
            'data': [
                {'y': df['AAPL.Volume'], 'x': df['Date'], 'type': 'bar', 'name': 'Volume'},
            ],
            'layout': {
                'plot_bgcolor': colors['background'],
                'paper_bgcolor': colors['background'],
                'font': {
                    'color': colors['text']
                }
            }
        }
    ),


])



if __name__ == '__main__':
    app.run_server(debug=True)

【问题讨论】:

    标签: python plotly-dash


    【解决方案1】:

    我对您的代码进行了以下更改:

    • 使用 plotly.graph_objects 从另一个图的重新布局选择触发的回调中配置了两个图。在 graph1 上执行的每个重新布局都会触发 graph2 配置,反之亦然
    • 重新布局数据以 dict 形式出现,我必须将其键转换为 str 才能访问其值。
    • 根据一张图表的重新布局数据,使用update_xaxes正确配置另一张图表的 x 轴范围。

    现在,根据一个图表中的 x 轴范围选择,另一个图表会自动更新。我在 graph2 下方添加了一个降价项,以便您可以跟踪重新布局数据字典及其值。

    import dash
    import dash_core_components as dcc
    import dash_html_components as html
    import plotly.graph_objects as go
    import ssl
    import pandas as pd
    from dash.dependencies import Input, Output
    
    external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
    
    ssl._create_default_https_context = ssl._create_unverified_context
    colors = {'background': '#111111',
              'text': '#7FDBFF'}
    
    df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv")
    
    app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
    
    #Sets df1 for graph1
    df1 = df[['Date', 'AAPL.Open', 'AAPL.High']]
    df1.columns = ['Date', 'Activity', 'Baseline']
    
    #Sets df2 for graph2
    df2 = df[['Date', 'AAPL.Volume']]
    df2.columns = ['Date', 'Volume']
    
    #App layout
    app.layout = html.Div(style={'backgroundColor': colors['background']}, 
                          children=[
        
        html.H1(children='graph1',
                style={'textAlign': 'center',
                       'color': colors['text']}),
    
        html.Div(children='Displaying Apple High and Low.', 
                 style={'textAlign': 'center',
                        'color': colors['text']}),
    
        dcc.Graph(id='graph1'),
    
        html.Div(children='Second Graph (Volume).', 
                 style={'textAlign': 'center',
                        'color': colors['text']}),
        dcc.Graph(id='graph2'),
        
        #item to track x axis relayout data
        dcc.Markdown(id= 'axis_data'),
    
    ])
    
    @app.callback(
        Output('graph2', 'figure'),
        Input('graph1', 'relayoutData'))
    
    def relayout_graph2(xaxis_config):
    
        figure2 = go.Figure()
        figure2.add_trace(go.Scatter(x = df2.Date, y = df2.Volume, name = 'Volume'))
        figure2.update_layout(plot_bgcolor = colors['background'],
                              paper_bgcolor = colors['background'],
                              font_color = colors['text'],
                              showlegend = True)
        
        if not xaxis_config:
            pass
        
        else:
            
            #For some reason it's necessary to convert the relayout dict keys to strings
            keys_values = xaxis_config.items()
            xaxis = {str(key): value for key, value in keys_values}
            
            try:
                if 'autosize' in xaxis.keys():
                    pass
                elif 'xaxis.autorange' in xaxis.keys():
                    figure2.update_xaxes(autorange = True)
                else:
                    figure2.update_xaxes(range=[xaxis['xaxis.range[0]'],xaxis['xaxis.range[1]']])
            
            except:
                pass
        
        return figure2
    
    @app.callback(
        Output('graph1', 'figure'),
        Input('graph2', 'relayoutData'))
    
    def relayout_graph1(xaxis_config):
    
        figure1 = go.Figure()
        figure1.add_trace(go.Scatter(x = df1.Date, y = df1.Activity, name = 'Activity'))
        figure1.add_trace(go.Scatter(x = df1.Date, y = df1.Baseline, name = 'Baseline'))
        figure1.update_layout(plot_bgcolor = colors['background'],
                              paper_bgcolor = colors['background'],
                              font_color = colors['text'])
        
        if not xaxis_config:
            pass
        
        else:
            
            #For some reason it's necessary to convert the relayout dict keys to strings
            keys_values = xaxis_config.items()
            xaxis = {str(key): value for key, value in keys_values}
            
            try:
                if 'autosize' in xaxis.keys():
                    pass
                elif 'xaxis.autorange' in xaxis.keys():
                    figure1.update_xaxes(autorange = True)
                else:
                    figure1.update_xaxes(range=[xaxis['xaxis.range[0]'],xaxis['xaxis.range[1]']])
            
            except:
                pass
        
        return figure1
    
    @app.callback(
        Output('axis_data', 'children'),
        [Input('graph1', 'relayoutData'),
         Input('graph2', 'relayoutData')])
    
    def read_relayout(data1, data2):
        
        return str(data1) + '///' + str(data2)
    
    if __name__ == '__main__':
        app.run_server(debug=True, port = 8888)

    【讨论】:

      猜你喜欢
      • 2015-09-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-01
      • 1970-01-01
      • 2021-08-30
      • 2020-09-12
      • 2013-02-25
      • 2012-12-15
      相关资源
      最近更新 更多