如何基于绘图选区移除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
相关产品推荐
相关产品推荐

