Plotly-Dash: How to code interactive callbacks for hover functions in plotly dash

邮差的信 提交于 2020-12-13 03:19:18

问题


Is it possible to have a text field at the bottom of a graph in dash that displays the text for the point they are on (showing hover data as plain text). So the text box will be able to make changes when users hover over a certain point. I have defined a dcc.Graph component and the app layout but am not sure how to define the callback function for the hoverdata.

I have used the below code to define dcc.Graph and 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'})
])

Any help with the callback will be great. thanks in advance


回答1:


Yes, that's very possible! Since you haven't provided a complete description of your setup, I've put together a minimal example that draws on elements from dash.plotly.com/interactive-graphing and https://community.plotly.com/: Use Hover Trace As Input for Callback that among other things describes the use of hover data in callbacks. The code snippet below will produce the following app for JupyterDash. If you'd like to run a standard dash app, just rewrite it following these steps.

The solution I've put together should do exactly what you're aiming for. Every time you hover over a point on one of the lines in the figure in the dcc.Graph component, a set of details about the trace is displayed in the html.Pre component under it, such as x and y values. Try it out and let me know how it works out for you!

App 1:

If you'd like to retrieve only certain elements of the output, you can subset the output like this:

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

App 2:

Complete code for 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)

Complete code for 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)


来源:https://stackoverflow.com/questions/64817038/plotly-dash-how-to-code-interactive-callbacks-for-hover-functions-in-plotly-das

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!