Tooltips of a figure are only displayed while hovering over the data point: https://plotly.com/python/hover-text-and-formatting
I'd like to have an easy way to customize the duration the tooltip is displayed after hovering over it or possibly display the tooltip permanently when clicking the data point.
This will allow me to include clickable links in the tooltip.
For data tables you can customize the tooltip display duration, but I don't see a similar option for figures: https://dash.plotly.com/datatable/tooltips
I think you can add your own tooltips via the event system or maybe change the css style of the resulting HTML somehow, but that seems to be overkill. I'd still accept an answer with a working example.
Here is a more complex solution that prevents the tooltip to fade out while you hover over it. For that you need an external css file with a css animation.
See https://stackoverflow.com/a/75277310/2474025 for a more simple solution.
assets/my.css:
.hideclass:not(:hover) {
animation: hideanimation 5s ease-in;
animation-fill-mode: forwards;
}
.showclass {
animation: showanimation 5s ease-out;
animation-fill-mode: forwards;
}
@keyframes showanimation {
0% {
opacity: 0;
}
25% {
opacity: 0.4;
}
50% {
opacity: 0.7;
}
75% {
opacity: 0.8;
}
100% {
opacity: 1;
}
}
@keyframes hideanimation {
0% {
opacity: 1;
}
25% {
opacity: 0.5;
}
50% {
opacity: 0;
}
75% {
opacity: 0;
max-width: 0;
max-height: 0;
overflow: hidden;
}
100% {
opacity: 0;
max-width: 0;
max-height: 0;
overflow: hidden;
}
}
Python notebook with the following code needs to be in the same directory as the assets folder:
from dash import Dash, dcc, html, Input, Output, no_update
import plotly.express as px
df = px.data.tips()
fig = px.scatter(df, x='total_bill', y='tip')
# Turn off native plotly.js hover effects - make sure to use
# hoverinfo='none' rather than 'skip' which also halts events.
fig.update_traces(hoverinfo='none', hovertemplate=None)
# Hover distance defaults to 20 and means call hover event if mouse pointer is within x units close to the node.
fig.update_layout(hoverdistance=5)
app = Dash(__name__)
app.layout = html.Div(
[
html.Link(rel='stylesheet', href='/assets/my.css'),
# clear on unhover means the hover callback is called with hoverDate=None when moving away from the point.log_queue
dcc.Graph(
id='graph-basic-2',
figure=fig,
clear_on_unhover=True,
),
html.Div(
id='graph-tooltip',
className='dash-bootstrap',
),
],
className='dash-bootrstrap',
)
previous_style = None
@app.callback(
Output('graph-tooltip', 'style'),
Output('graph-tooltip', 'className'),
Output('graph-tooltip', 'children'),
Input('graph-basic-2', 'hoverData'),
prevent_initial_call=True,
)
def display_hover(hoverData):
global previous_style
if hoverData is None:
return no_update, 'hideclass', no_update
print('display')
# demo only shows the first point, but other points may also be available
pt = hoverData['points'][0]
bbox = pt['bbox']
children = [
html.A('Link to external site 1', href='https://plot.ly', target='_blank'),
html.Br(),
html.A('Link to external site 2', href='https://plot.ly', target='_blank'),
]
previous_style = {
'position': 'absolute',
'left': f'{bbox["x1"] + 20}px',
'top': f'{bbox["y1"] + 20}px',
'background-color': 'rgba(100, 100, 100, 0.8)',
'padding': '1em',
}
return previous_style, 'showclass', children
# if __name__ == '__main__':
app.run_server(
dev_tools_hot_reload=True,
)