在Matplotlib工具栏添加Process按钮实现数据处理功能
给Matplotlib工具栏添加自定义Process按钮实现选中数据处理
原代码通过SpanSelector在上方子图选择区域,按z键后处理选中数据并展示在下方子图。现在我们移除键盘触发,改为在工具栏添加一个Process按钮,点击按钮执行相同的数据处理操作:
修改后的完整代码
import pandas as pd import matplotlib.pyplot as plt from matplotlib.widgets import SpanSelector import matplotlib.dates as mdates from matplotlib.backend_tools import ToolBase if __name__ == '__main__': idx = pd.date_range("2018-01-01", "2018-01-03", freq="10s") df = pd.DataFrame(range(len(idx)), index=idx, columns=['val_phys']) date_min = df.index.values[0] date_max = df.index.values[len(df) - 1] # 布局与样式设置 plt.rcParams['figure.constrained_layout.use'] = True plt.rcParams['date.converter'] = 'concise' plt.rcParams['axes.grid'] = True fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True) tb = fig.canvas.toolbar ax1.plot(df) # 设置初始x轴范围 ax1.set_xlim([mdates.date2num(date_min), mdates.date2num(date_max)]) ax2.set_xlim(ax1.get_xlim()) # 将初始视图压入工具栏历史栈 tb.push_current() # 封装数据处理逻辑为独立函数 def process_selected_data(): # 筛选选中时间范围内的数据 df_selected = df.loc[(df.index >= date_min) & (df.index <= date_max)] # 降采样:每5分钟保留一个样本(30个10秒样本) df_selected = df_selected.iloc[::30] ax2.clear() ax2.set_xlim(ax1.get_xlim()) ax2.plot(df_selected) ax2.autoscale(enable=True, axis="y", tight=False) plt.draw() def on_select(xmin, xmax): global date_min, date_max date_min = mdates.num2date(xmin).replace(tzinfo=None) date_max = mdates.num2date(xmax).replace(tzinfo=None) ax1.set_xlim([xmin, xmax]) visible_y = df.loc[(df.index >= date_min) & (df.index <= date_max)].val_phys if len(visible_y): ax1.set_ylim(min(visible_y), max(visible_y)) ax2.set_xlim(ax1.get_xlim()) tb.push_current() plt.draw() # 自定义工具栏工具类 class ProcessTool(ToolBase): # 设置工具ID和按钮描述 default_keymap = '' description = 'Process Selected Data' def trigger(self, *args, **kwargs): process_selected_data() # 将自定义工具注册到工具管理器 fig.canvas.manager.toolmanager.add_tool('Process', ProcessTool) # 在工具栏添加按钮(加入默认工具组) fig.canvas.manager.toolbar.add_tool('Process', 'toolgroup') # 初始化SpanSelector span_selector = SpanSelector(ax1, on_select, direction='horizontal', useblit=True) plt.show()
关键修改说明
- 封装处理逻辑:把原键盘事件里的数据处理代码抽成独立的
process_selected_data函数,统一调用入口。 - 自定义工具栏按钮:
- 继承
ToolBase创建ProcessTool类,在trigger方法中调用处理函数,触发按钮点击动作。 - 通过工具管理器注册工具,再将按钮添加到工具栏默认分组,和原生按钮排列在一起。
- 继承
- 移除键盘触发:删掉原有的键盘事件绑定,完全通过工具栏按钮执行数据处理。
注:如果需要自定义按钮图标,可给
ProcessTool类添加default_icon属性,指向你的图标文件路径;不设置则使用Matplotlib默认按钮样式。
内容的提问来源于stack exchange,提问作者Alessandro
相关产品推荐
相关产品推荐

