Plotly-Dash: So codieren Sie interaktive Rückrufe für Hover-Funktionen in Plotly Dash

Nov 13 2020

Ist es möglich, ein Textfeld am unteren Rand eines Diagramms im Bindestrich zu haben, das den Text für den Punkt anzeigt, an dem sie sich befinden (Schwebedaten werden als einfacher Text angezeigt). Das Textfeld kann also Änderungen vornehmen, wenn Benutzer mit der Maus über einen bestimmten Punkt fahren. Ich habe eine dcc.Graph-Komponente und das App-Layout definiert, bin mir aber nicht sicher, wie ich die Rückruffunktion für die Hoverdata definieren soll.

Ich habe den folgenden Code verwendet, um dcc.Graph und app.layout zu definieren

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'})
])

Jede Hilfe beim Rückruf wird großartig sein. Danke im Voraus

Antworten

2 vestland Nov 13 2020 at 17:01

Ja, das ist sehr gut möglich! Da Sie keine vollständige Beschreibung Ihres Setups angegeben haben, habe ich ein minimales Beispiel zusammengestellt, das auf Elementen von dash.plotly.com/interactive-graphing und basierthttps://community.plotly.com/: Use Hover Trace As Input for Callbackdas beschreibt unter anderem die Verwendung von Schwebedaten in Rückrufen. Das folgende Code-Snippet erzeugt die folgende App für JupyterDash. Wenn Sie möchten , dass ein Standard - dash App laufen, umschreiben es einfach folgende diese Schritte .

Die Lösung, die ich zusammengestellt habe, sollte genau das tun, was Sie anstreben. Jedes Mal , wenn Sie schweben über einem Punkt auf einer der Linien in der Figur in der dcc.Graph Komponente, eine Reihe von Details über die Spur wird in der angezeigten html.Pre Komponente unter ihm, wie x und y - Werte. Probieren Sie es aus und lassen Sie mich wissen, wie es für Sie funktioniert!

App 1:

Wenn Sie nur bestimmte Elemente der Ausgabe abrufen möchten, können Sie die Ausgabe wie folgt unterteilen:

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

App 2:

Vollständiger Code für 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)

Vollständiger Code für 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)