4

Suppose I have a scatterplot in plotly (python). When I hover over a point, I see the hover of the points x and y immediately. But what I want to do it click on the point, then the hover text will appear (and stay). And when I click on another point, the hover text will appear there for that point. How do I do this?

4
  • According to this forum post, it appears that modifying hoverevents in this way may be possible in plotly.js, but is probably not possible in python. would you consider a plotly.js based solution? Commented Nov 30, 2021 at 18:46
  • @DerekO, I do know the solution with plotly.js. I need it in python. I have updated my question accordingly. Commented Nov 30, 2021 at 18:54
  • in python, I don't think such a functionality is possible without some sort of hack. you could do something like hide the hovertext completely, and have a textbox associated with each marker and change its visibility when the marker is clicked. if i figure out such a solution, i'd be happy to post an answer Commented Nov 30, 2021 at 19:07
  • 1
    @DerekO, Such a solution is much appreciated. Commented Dec 1, 2021 at 15:20

1 Answer 1

2

As mentioned in the comments, I don't believe you can create this functionality in plotly python because this library alone can't process clickevents on markers.

However, in plotly-dash you can use callbacks to process clickData (see the documentation for an example), and this will allow you to modify the figure when the user clicks on a marker.

Since you want to display text next to each marker, I thought the easiest solution would be to have the text associated with each trace (with one marker per trace) and set the opacity of the text to 0 so it doesn't display initially. Then when the user clicks on the marker, the opacity of the text changes to 1 if it is 0, or changes to 0 when the opacity is 1. Also you can pass the argument hoverinfo='none' to hide the default hoverinfo that Plotly displays with each marker.

import plotly.graph_objects as go
import dash
from dash import dcc, html
from dash.dependencies import Input, Output

app = dash.Dash()

x_array = [1,2,3,4]
y_array = [5,6,7,8]
text_array = [f"x:{x}<br>y:{y}" for (x,y) in zip(x_array,y_array)]

fig = go.Figure()
for (x,y,text) in zip(x_array,y_array,text_array):
    fig.add_trace(go.Scatter(
        x=[x],
        y=[y],
        text=[text],
        marker=dict(color="blue", size=20),
        textfont=dict(color='rgba(0,0,0,0)'),
        textposition="middle right",
        mode="markers+text",
        hoverinfo='none',
        showlegend=False
    ))
fig.update_layout(title="Display Hovertext when Clicked", title_x=0.5)
fig.update_yaxes(range=[4,10])

app.layout = html.Div(children=[
    dcc.Graph(
        id='example-graph',
        figure=fig
    )
])

@app.callback(
    Output('example-graph', 'figure'),
    [Input('example-graph', 'clickData')])
def toggle_text(clickData, fig=fig, x_array=x_array, y_array=y_array, text_array=text_array):
    if clickData is None:
        return fig
    else:
        trace_number = clickData['points'][0]['curveNumber']
        trace_color = fig.data[trace_number].textfont.color
        # print(f"you clicked on trace_number {trace_number} with color {trace_color}")
        if fig.data[trace_number].textfont.color == 'rgba(0,0,0,0)':
            # print(f"setting trace_number {trace_number} invisible to visible")
            fig.data[trace_number].textfont.color = 'rgba(0,0,0,1)'
        elif fig.data[trace_number].textfont.color == 'rgba(0,0,0,1)':
            # print(f"setting trace_number {trace_number} visible to invisible")
            fig.data[trace_number].textfont.color = 'rgba(0,0,0,0)'
        return fig

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

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.