首页 > 解决方案 > Plotly/Dash -- 范围过滤器在 hoverData 上重置

问题描述

我正在尝试使用 Dash 捕获鼠标悬停事件。我使用捕获鼠标的位置hoverData

当我使用范围选择器或范围滑块过滤时间序列时出现问题。该图正确地减少到选定的时间,但是当我用鼠标悬停它时,它会重置为主视图(整个主系列)。

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go
from dash.dependencies import Input, Output

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

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

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

app.layout = html.Div([
    dcc.Graph(
        id='stock-plot'
    ),
], className="container")

@app.callback(
    Output('stock-plot', 'figure'),
    [Input('stock-plot', 'hoverData')])
def drawStockPrice(hoverData):
    traces = [go.Scatter(
                    x=df.Date,
                    y=df['AAPL.High'],
                    mode='lines',
                    opacity=0.7,
                    connectgaps=True),
            ]
    return {'data': traces,
            'layout': go.Layout(colorway=["#5E0DAC", '#FF4F00', '#375CB1', '#FF7400', '#FFF400', '#FF0056'],
                                          height=600,
                                          title=f"Closing prices",
                                          xaxis={"title": "Date",
                                                 'rangeselector': {'buttons': list([{'count': 1, 'label': '1M',
                                                                                     'step': 'month',
                                                                                     'stepmode': 'backward'},
                                                                                    {'count': 6, 'label': '6M',
                                                                                     'step': 'month',
                                                                                     'stepmode': 'backward'},
                                                                                    {'step': 'all'}])},
                                                 'rangeslider': {'visible': True}, 'type': 'date'},
                                          yaxis={"title": "Price (USD)"},
    )}

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

标签: pythonpython-3.xplotlyplotly-dash

解决方案


我确信应该有更好的解决方案,但这就是我得到的(Dash v1.6.0):

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go
from dash.dependencies import Input, Output, State

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv")

layout = go.Layout( colorway=["#5E0DAC", '#FF4F00', '#375CB1', '#FF7400', '#FFF400', '#FF0056'],
                    height=600,
                    title=f"Closing prices",
                    xaxis={"title": "Date",
                           'rangeselector': {'buttons': list([{'count': 1, 'label': '1M',
                                                               'step': 'month',
                                                               'stepmode': 'backward'},
                                                              {'count': 6, 'label': '6M',
                                                               'step': 'month',
                                                               'stepmode': 'backward'},
                                                              {'step': 'all'}]
                                              ),  
                           },
                           'rangeslider': {'visible': True}, 
                           'type': 'date',            
                    },
                    yaxis={"title": "Price (USD)"},
)

traces = [go.Scatter(   x=df.Date,
                        y=df['AAPL.High'],
                        mode='lines',
                        opacity=0.7,
                        connectgaps=True
)]

app.layout = html.Div([
    dcc.Graph(
        id='stock-plot',
        figure={
            'data': traces,
            'layout': layout
        }        
    ),
], className="container")

@app.callback(
    Output('stock-plot', 'figure'),
    [Input('stock-plot', 'hoverData'),
     Input('stock-plot', 'relayoutData')],
    [State('stock-plot', 'figure')]
)
def drawStockPrice(hoverData, selected, figure):
    data = figure['data']
    layout = figure['layout']

    if selected is not None and 'xaxis.range' in selected:
        layout['xaxis']['range'] = selected['xaxis.range']

    return {'data': data,
            'layout': layout
    }

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

在此处输入图像描述


推荐阅读