Plotly-Dash: Cómo codificar devoluciones de llamada interactivas para funciones de desplazamiento en plotly dash

Nov 13 2020

¿Es posible tener un campo de texto en la parte inferior de un gráfico en un guión que muestre el texto del punto en el que se encuentran (mostrando los datos flotantes como texto sin formato)? Por lo tanto, el cuadro de texto podrá realizar cambios cuando los usuarios pasen el cursor sobre un punto determinado. He definido un componente dcc.Graph y el diseño de la aplicación, pero no estoy seguro de cómo definir la función de devolución de llamada para el hoverdata.

He usado el siguiente código para definir dcc.Graph y 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'})
])

Cualquier ayuda con la devolución de llamada será genial. gracias por adelantado

Respuestas

2 vestland Nov 13 2020 at 17:01

¡Sí, eso es muy posible! Como no proporcionó una descripción completa de su configuración, he reunido un ejemplo mínimo que se basa en elementos de dash.plotly.com/interactive-graphing yhttps://community.plotly.com/: Use Hover Trace As Input for Callbackque, entre otras cosas, describe el uso de datos flotantes en devoluciones de llamada. El siguiente fragmento de código producirá la siguiente aplicación para JupyterDash. Si desea ejecutar una aplicación de tablero estándar, simplemente vuelva a escribirla siguiendo estos pasos .

La solución que he elaborado debería hacer exactamente lo que está buscando. Cada vez que pasa el cursor sobre un punto en una de las líneas de la figura en el componente dcc.Graph , se muestra un conjunto de detalles sobre la traza en el componente html.Pre debajo de él, como los valores xey. ¡Pruébelo y cuénteme cómo le funciona!

Aplicación 1:

Si desea recuperar solo ciertos elementos de la salida, puede crear subconjuntos de la salida de la siguiente manera:

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

Aplicación 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)