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

如何基于绘图选区移除DataFrame中的数据点

手动移除实验数据伪影尖峰的Plotly交互式实现

我有实验数据存在伪影尖峰问题,需要快速手动选择并移除这些随机尖峰。对比Plotly、Bokeh和Altair后选择Plotly实现交互式方案,已完成初步代码,但无法实现点击按钮移除选中区域数据的功能。

原始尝试代码

import pandas as pd
import plotly.graph_objects as go
from ipywidgets import interactive, HBox, VBox, Button

url='https://drive.google.com/file/d/1hCX8Bn_y30aXVN_TyHTTx015u44pO9yB/view?usp=sharing'
url='https://drive.google.com/uc?id=' + url.split('/')[-2]

df = pd.read_csv(url, index_col=0)

f = go.FigureWidget()
for col in df.columns[-1:]: 
    f.add_scatter(x = df.index, y=df[col], mode='markers+lines', 
                  selected_marker=dict(size=5, color='red'),
                  marker=dict(size=1, color='lightgrey', line=dict(width=1, color='lightgrey')))
    
t = go.FigureWidget([go.Table(
    header=dict(values=['selector range'],
                fill = dict(color='#C2D4FF'),
                align = ['left'] * 5),
    cells=dict(values=['None selected' for col in ['ID']],
               fill = dict(color='#F5F8FF'),
               align = ['left'] * 5)
                )])
    
def selection_fn(trace,points,selector):
    t.data[0].cells.values = [selector.xrange]


def update_axes(dataset):
    scatter = f.data[0]
    scatter.x = df.index
    scatter.y = df[dataset]
    
f.data[0].on_selection(selection_fn)


axis_dropdowns = interactive(update_axes, dataset = df.columns)

button1 = Button(description="Remove points")
button2 = Button(description="Reset")
button3 = Button(description="Fit data")


VBox((HBox((axis_dropdowns.children)), HBox((button1, button2, button3)), f,t))

遇到的问题

已能获取选择框的x坐标并显示在表格中,但无法给button1绑定函数,实现接收选择框坐标→移除DataFrame对应点→重绘数据的逻辑。预期函数逻辑如下:

def on_button_click_remove(scatter.selector.xrange):
    mask = (df.index >= scatter.selector.xrange[0]) & (df.index <= scatter.selector.xrange[1]) 
    clean_df = df.drop(df.index[mask])
    scatter(data = clean_df...) #update scatter plot

button1 = Button(description="Remove points", on_click = on_button_click_remove)

解决方案代码

import pandas as pd
import plotly.graph_objects as go
from ipywidgets import interactive, HBox, VBox, Button

# 加载数据
url='https://drive.google.com/file/d/1hCX8Bn_y30aXVN_TyHTTx015u44pO9yB/view?usp=sharing'
url='https://drive.google.com/uc?id=' + url.split('/')[-2]
df = pd.read_csv(url, index_col=0)
# 保存原始数据用于重置
original_df = df.copy()
# 当前使用的数据集
current_df = df.copy()

# 创建交互式图表
f = go.FigureWidget()
scatter = f.add_scatter(x=current_df.index, y=current_df[current_df.columns[-1]], 
                        mode='markers+lines', 
                        selected_marker=dict(size=5, color='red'),
                        marker=dict(size=1, color='lightgrey', line=dict(width=1, color='lightgrey')))

# 创建选择范围显示表格
t = go.FigureWidget([go.Table(
    header=dict(values=['selector range'],
                fill=dict(color='#C2D4FF'),
                align=['left']),
    cells=dict(values=['None selected'],
               fill=dict(color='#F5F8FF'),
               align=['left'])
)])

# 存储选中的x范围
selected_xrange = None

# 选择事件处理函数
def selection_fn(trace, points, selector):
    global selected_xrange
    selected_xrange = selector.xrange
    t.data[0].cells.values = [selected_xrange if selected_xrange else 'None selected']

# 更新图表数据(切换数据集)
def update_axes(dataset):
    global current_df
    current_df = original_df.copy()
    scatter.x = current_df.index
    scatter.y = current_df[dataset]
    t.data[0].cells.values = ['None selected']

# 移除选中区域数据
def on_button_click_remove(b):
    global current_df
    if not selected_xrange:
        return
    # 过滤掉选中范围内的数据
    mask = (current_df.index >= selected_xrange[0]) & (current_df.index <= selected_xrange[1])
    current_df = current_df.drop(current_df.index[mask])
    # 更新图表
    scatter.x = current_df.index
    scatter.y = current_df[current_df.columns[scatter.y.index[0]]]
    # 清空选择范围显示
    t.data[0].cells.values = ['None selected']

# 重置数据和图表
def on_button_click_reset(b):
    global current_df, selected_xrange
    current_df = original_df.copy()
    selected_xrange = None
    # 恢复当前选中数据集的显示
    scatter.x = current_df.index
    scatter.y = current_df[current_df.columns[scatter.y.index[0]]]
    t.data[0].cells.values = ['None selected']

# 绑定事件
scatter.on_selection(selection_fn)
axis_dropdowns = interactive(update_axes, dataset=df.columns)
button1 = Button(description="Remove points")
button1.on_click(on_button_click_remove)
button2 = Button(description="Reset")
button2.on_click(on_button_click_reset)
button3 = Button(description="Fit data")

# 布局显示
VBox((HBox((axis_dropdowns.children)), HBox((button1, button2, button3)), f, t))

关键修改说明

  • 新增selected_xrange全局变量存储选中的x范围,解决按钮点击时无法获取选择框坐标的问题
  • 保存original_df用于重置功能,避免数据丢失后无法恢复
  • 实现on_button_click_remove函数:通过选中的x范围过滤数据,直接更新图表的x和y属性完成重绘
  • 实现on_button_click_reset函数:恢复原始数据并重置图表显示
  • 给按钮绑定对应的点击事件,完成交互逻辑闭环

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 04:20:32