Plotly-Dash: como codificar callbacks interativos para funções de foco no plotly Dash

Nov 13 2020

É possível ter um campo de texto na parte inferior de um gráfico em traço que exibe o texto para o ponto em que estão (mostrando os dados de foco como texto simples). Portanto, a caixa de texto poderá fazer alterações quando os usuários passarem o mouse sobre um determinado ponto. Eu defini um componente dcc.Graph e o layout do aplicativo, mas não tenho certeza de como definir a função de retorno de chamada para hoverdata.

Usei o código abaixo para definir dcc.Graph e app.layout

fig = go.Figure(data=plot_data, layout=plot_layout)

app.layout = html.Div([
    dcc.Graph(figure=fig),
    
        html.Div([
                    dcc.Markdown(id='mpg-metrics')
                ],style={'width':'20%','display':'inline-block'})
])

Qualquer ajuda com o retorno de chamada será ótimo. desde já, obrigado

Respostas

2 vestland Nov 13 2020 at 17:01

Sim, isso é muito possível! Já que você não forneceu uma descrição completa de sua configuração, juntei um exemplo mínimo que se baseia em elementos de dash.plotly.com/interactive-graphing ehttps://community.plotly.com/: Use Hover Trace As Input for Callbackque, entre outras coisas, descreve o uso de dados flutuantes em retornos de chamada. O snippet de código abaixo produzirá o seguinte aplicativo para JupyterDash. Se você gostaria de executar um aplicativo de painel padrão, basta reescrevê-lo seguindo estas etapas .

A solução que criei deve fazer exatamente o que você deseja. Cada vez que você passa o mouse sobre um ponto em uma das linhas da figura no componente dcc.Graph , um conjunto de detalhes sobre o traço é exibido no componente html.Pre abaixo dele, como os valores x e y. Experimente e diga-me como funciona para você!

App 1:

Se quiser recuperar apenas alguns elementos da saída, você pode definir um subconjunto da saída desta forma:

json.dumps({'Date:':hoverData['points'][0]['x'],
            'Value:':hoverData['points'][0]['y']}, indent = 2)

App 2:

Código completo para JupyterDash, App1

import json
from textwrap import dedent as d
import pandas as pd
import plotly.graph_objects as go
import numpy as np
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
from dash.dependencies import Input, Output
from jupyter_dash import JupyterDash

# app info
app = JupyterDash(__name__)

styles = {
    'pre': {
        'border': 'thin lightgrey solid',
        'overflowX': 'scroll'
    }
}

# data and basic figure
x = np.arange(20)+10

fig = go.Figure(data=go.Scatter(x=x, y=x**2, mode = 'lines+markers'))
fig.add_traces(go.Scatter(x=x, y=x**2.2, mode = 'lines+markers'))

app.layout = html.Div([
    dcc.Graph(
        id='basic-interactions',
        figure=fig,
    ),

    html.Div(className='row', children=[
        html.Div([
            dcc.Markdown(d("""
              Click on points in the graph.
            """)),
            html.Pre(id='hover-data', style=styles['pre']),
        ], className='three columns'),
    ])
])


@app.callback(
    Output('hover-data', 'children'),
    [Input('basic-interactions', 'hoverData')])
def display_hover_data(hoverData):
    return json.dumps(hoverData, indent=2)

app.run_server(mode='external', port = 8070, dev_tools_ui=True,
          dev_tools_hot_reload =True, threaded=True)

Código completo para JupyterDash, App2

import json
from textwrap import dedent as d
import pandas as pd
import plotly.graph_objects as go
import numpy as np
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
from dash.dependencies import Input, Output
from jupyter_dash import JupyterDash

# app info
app = JupyterDash(__name__)

styles = {
    'pre': {
        'border': 'thin lightgrey solid',
        'overflowX': 'scroll'
    }
}

# data and basic figure
y = np.arange(100)+10
x = pd.date_range(start='1/1/2021', periods=len(y))

fig = go.Figure(data=go.Scatter(x=x, y=y**2, mode = 'lines+markers'))
fig.add_traces(go.Scatter(x=x, y=y**2.2, mode = 'lines+markers'))

app.layout = html.Div([
    dcc.Graph(
        id='basic-interactions',
        figure=fig,
    ),

    html.Div(className='row', children=[
        html.Div([
            dcc.Markdown(d("""
              Click on points in the graph.
            """)),
            html.Pre(id='hover-data', style=styles['pre']),
        ], className='three columns'),
    ])
])


@app.callback(
    Output('hover-data', 'children'),
    [Input('basic-interactions', 'hoverData')])
def display_hover_data(hoverData):
    try:
        return json.dumps({'Date:':hoverData['points'][0]['x'],
                           'Value:':hoverData['points'][0]['y']}, indent = 2)
    except:
        return None

app.run_server(mode='external', port = 8070, dev_tools_ui=True,
          dev_tools_hot_reload =True, threaded=True)