如何在Plotly中实现鼠标悬停时标记点放大高亮效果?
实现Plotly散点图标记点悬停放大效果
要实现鼠标悬停时标记点放大、移开后恢复的效果,Plotly默认没有该功能,需要通过自定义交互逻辑实现,下面提供两种可行方案:
方案1:用Dash做交互式回调
Dash是Plotly的交互式框架,通过监听鼠标悬停事件动态修改标记大小:
import dash from dash import dcc, html, Input, Output, State import plotly.graph_objects as go x = [1, 2, 3, 4, 5] y = [1, 2, 3, 4, 5] default_size = 8 # 初始标记大小 hover_size = 16 # 悬停时的标记大小 # 初始化图表 fig = go.Figure() fig.add_trace(go.Scatter( x=x, y=y, mode='lines+markers', marker=dict(size=[default_size]*len(x)) )) # 搭建Dash应用 app = dash.Dash(__name__) app.layout = html.Div([ dcc.Graph(id='scatter-graph', figure=fig) ]) # 回调函数:根据悬停状态更新标记大小 @app.callback( Output('scatter-graph', 'figure'), Input('scatter-graph', 'hoverData'), State('scatter-graph', 'figure') ) def update_marker_size(hover_data, fig): if not hover_data: # 无悬停时恢复所有标记的初始大小 fig['data'][0]['marker']['size'] = [default_size]*len(x) return fig # 获取当前悬停点的索引 point_idx = hover_data['points'][0]['pointIndex'] # 仅放大悬停点,其余保持初始大小 fig['data'][0]['marker']['size'] = [ hover_size if i == point_idx else default_size for i in range(len(x)) ] return fig if __name__ == '__main__': app.run_server(debug=True)
运行后,鼠标悬停在任意标记点上时,该点会立刻放大,移开鼠标后自动恢复原尺寸。
方案2:直接在HTML中注入JS脚本
如果不想用Dash,也可以在生成HTML文件时嵌入自定义JavaScript,监听Plotly的悬停事件:
import plotly.graph_objects as go x = [1, 2, 3, 4, 5] y = [1, 2, 3, 4, 5] default_size = 8 hover_size = 16 # 创建基础散点图 fig = go.Figure() fig.add_trace(go.Scatter( x=x, y=y, mode='lines+markers', marker=dict(size=[default_size]*len(x)) )) # 自定义JS脚本,监听悬停和离开事件 custom_js = f""" <script> const defaultSize = {default_size}; const hoverSize = {hover_size}; const plotDiv = document.getElementById('{fig.layout.id}'); // 鼠标悬停时放大对应点 plotDiv.addEventListener('plotly_hover', (data) => {{ const pointIndex = data.points[0].pointIndex; const update = {{'marker.size': []}}; for (let i = 0; i < {len(x)}; i++) {{ update['marker.size'].push(i === pointIndex ? hoverSize : defaultSize); }} Plotly.restyle(plotDiv, update, 0); }}); // 鼠标移开时恢复所有点大小 plotDiv.addEventListener('plotly_unhover', () => {{ const update = {{'marker.size': Array({len(x)}).fill(defaultSize)}}; Plotly.restyle(plotDiv, update, 0); }}); </script> """ # 生成HTML并注入JS脚本 html_content = fig.to_html(full_html=True) html_content = html_content.replace('</body>', custom_js + '</body>') # 保存为HTML文件 with open('scatter_hover.html', 'w') as f: f.write(html_content)
运行代码后打开生成的scatter_hover.html,就能看到悬停放大的效果。
内容的提问来源于stack exchange,提问作者Bret Stuart
相关产品推荐
相关产品推荐

