You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Plotly Express scatter_matrix的套索选择取交集?附优化及R实现问询

实现Scatter Matrix的多次选择交集高亮

要把默认的并集高亮改成交集,需要通过自定义回调逻辑跟踪每次选择的数据集索引,计算交集后统一更新所有子图的选中状态。以下是基于Plotly Dash的实现方案:

import dash
from dash import dcc, html, Input, Output, State
import plotly.express as px
import numpy as np

df = px.data.iris()
fig = px.scatter_matrix(df,
    dimensions=df.columns[0:4],
    color=df.columns[4])
fig.update_layout(
    autosize=False,
    width=1200,
    height=1200,
)

app = dash.Dash(__name__)

app.layout = html.Div([
    dcc.Graph(id='scatter-matrix', figure=fig),
    html.Div(id='selected-indices-store', style={'display': 'none'}, children='[]')
])

@app.callback(
    Output('selected-indices-store', 'children'),
    Input('scatter-matrix', 'selectedData'),
    State('selected-indices-store', 'children'),
    prevent_initial_call=True
)
def update_selected_indices(selected_data, stored_indices):
    current_indices = [point['pointIndex'] for point in selected_data['points']]
    stored_indices = eval(stored_indices)
    
    if not stored_indices:
        return str(current_indices)
    else:
        intersection = list(set(stored_indices) & set(current_indices))
        return str(intersection)

@app.callback(
    Output('scatter-matrix', 'figure'),
    Input('selected-indices-store', 'children'),
    State('scatter-matrix', 'figure'),
    prevent_initial_call=True
)
def update_figure(selected_indices_str, fig):
    selected_indices = eval(selected_indices_str)
    num_traces = len(fig['data'])
    
    for i in range(num_traces):
        fig['data'][i]['selectedpoints'] = [idx for idx in selected_indices if idx < len(fig['data'][i]['x'])]
    
    return fig

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

核心逻辑:

  • 用隐藏组件存储历史选择的索引集合
  • 每次新选择时计算当前与历史选择的交集
  • 遍历所有子图,仅将交集内的点标记为选中状态

附加问题1:提升响应速度(类似scattergl)

Plotly Express的scatter_matrix默认使用scatter trace,手动替换为scattergl即可提升大数据量下的响应速度:

import plotly.express as px
df = px.data.iris()
fig = px.scatter_matrix(df,
    dimensions=df.columns[0:4],
    color=df.columns[4])

# 将所有scatter trace替换为scattergl
for trace in fig.data:
    trace.type = 'scattergl'

fig.update_layout(
    autosize=False,
    width=1200,
    height=1200,
)
fig.show()

替换后,选择、缩放等交互操作的响应速度会显著提升,适合十万级以上的数据量。


附加问题2:R语言实现交集选择

在R中可以用plotly结合shiny实现相同逻辑,核心思路与Python一致:

library(plotly)
library(shiny)
library(dplyr)

df <- iris
fig <- plot_ly(df) %>%
  add_trace(
    type = "scattermatrix",
    dimensions = list(
      list(label = "Sepal.Length", values = df$Sepal.Length),
      list(label = "Sepal.Width", values = df$Sepal.Width),
      list(label = "Petal.Length", values = df$Petal.Length),
      list(label = "Petal.Width", values = df$Petal.Width)
    ),
    color = df$Species
  ) %>%
  layout(
    autosize = FALSE,
    width = 1200,
    height = 1200
  )

ui <- fluidPage(
  plotlyOutput("scatter_matrix"),
  hidden(div(id = "selected_indices", ""))
)

server <- function(input, output, session) {
  output$scatter_matrix <- renderPlotly(fig)
  
  observeEvent(event_data("plotly_selected"), {
    current_selected <- event_data("plotly_selected")$pointIndex
    stored_selected <- input$selected_indices
    
    if (stored_selected == "") {
      new_selected <- current_selected
    } else {
      stored_selected <- as.integer(strsplit(stored_selected, ",")[[1]])
      new_selected <- intersect(stored_selected, current_selected)
    }
    
    updateTextInput(session, "selected_indices", value = paste(new_selected, collapse = ","))
  })
  
  observeEvent(input$selected_indices, {
    if (input$selected_indices == "") return()
    
    selected_indices <- as.integer(strsplit(input$selected_indices, ",")[[1]])
    fig_obj <- plotlyProxy("scatter_matrix", session)
    
    for (i in 1:length(fig_obj$x$data)) {
      plotlyProxyInvoke(fig_obj, "restyle", list(selectedpoints = list(selected_indices)), list(i-1))
    }
  })
}

shinyApp(ui, server)

通过shiny事件监听和plotlyProxy动态更新选中状态,实现交集高亮效果。


内容的提问来源于stack exchange,提问作者Noskario

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 11:07:34