如何让Dash散点图点击时返回多个点的名称?
实现Dash散点图多选点并返回多个名称
你的代码目前仅取了clickData['points']列表的第一个元素,因此只能返回单个值。要实现多选点并返回多个名称,需要调整点击模式并维护选中点的集合,具体修改如下:
关键修改说明
- 将图表的
clickmode设置为event+select,支持按住Ctrl(Windows/Linux)或Cmd(Mac)点击切换点的选中状态 - 添加
dcc.Store组件持久化存储选中的点名称,避免图表更新或页面交互后丢失选中状态 - 新增回调处理点击事件,动态更新选中集合(点击已选中的点则移除,未选中则添加)
- 最后将所有选中的名称以列表形式展示,提升可读性
修改后的完整代码
from dash import Dash, html, dcc, Input, Output, State import pandas as pd import plotly.express as px PCA_table=pd.read_excel('https://github.com/hoatranobita/Jobs/blob/main/PCA_table.xlsx?raw=true') external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css'] app = Dash(__name__, external_stylesheets=external_stylesheets) app.layout = html.Div([ html.Div([ html.Div([ dcc.Dropdown( options=PCA_table.columns.unique(), value='PC1', id='crossfilter-xaxis-column', )],style={'width': '49%', 'display': 'inline-block'}), html.Div([ dcc.Dropdown( options=PCA_table.columns.unique(), value='PC2', id='crossfilter-yaxis-column' )], style={'width': '49%', 'float': 'right', 'display': 'inline-block'}) ], style={'padding': '10px 5px'}), html.Div([ dcc.Graph( id='crossfilter-indicator-scatter', clickData={'points': [{'hovertext': '184A1'}]} )], style={'width': '49%', 'display': 'inline-block', 'padding': '0 20'}), html.Div([ html.Div(id='x-time-series'), ], style={'display': 'inline-block', 'width': '49%'}), # 存储选中点名称的组件 dcc.Store(id='selected-points', data=[]) ]) @app.callback( Output('crossfilter-indicator-scatter', 'figure'), Input('crossfilter-xaxis-column', 'value'), Input('crossfilter-yaxis-column', 'value')) def update_graph(xaxis_column_name, yaxis_column_name): fig = px.scatter(PCA_table,x=PCA_table[xaxis_column_name], y=PCA_table[yaxis_column_name], color=PCA_table['Labels'], hover_name=PCA_table['Columns']) # 设置支持多选的点击模式 fig.update_layout(clickmode='event+select') fig.update_layout(margin={'l': 40, 'b': 40, 't': 10, 'r': 0}, hovermode='closest') return fig @app.callback( Output('selected-points', 'data'), Input('crossfilter-indicator-scatter', 'clickData'), State('selected-points', 'data'), prevent_initial_call=True ) def update_selected_points(clickData, selected_points): # 获取当前点击的点名称 clicked_name = clickData['points'][0]['hovertext'] # 切换选中状态:已存在则移除,否则添加 if clicked_name in selected_points: selected_points.remove(clicked_name) else: selected_points.append(clicked_name) return selected_points @app.callback( Output('x-time-series', 'children'), Input('selected-points', 'data') ) def display_selected_points(selected_points): if not selected_points: return html.Span('未选中任何点') # 以列表形式展示所有选中的名称 return html.Ul([html.Li(name) for name in selected_points]) if __name__ == '__main__': app.run_server(debug=False,port=1111)
内容的提问来源于stack exchange,提问作者hoa tran
相关产品推荐
相关产品推荐

