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

在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()

关键修改说明

  1. 封装处理逻辑:把原键盘事件里的数据处理代码抽成独立的process_selected_data函数,统一调用入口。
  2. 自定义工具栏按钮:
    • 继承ToolBase创建ProcessTool类,在trigger方法中调用处理函数,触发按钮点击动作。
    • 通过工具管理器注册工具,再将按钮添加到工具栏默认分组,和原生按钮排列在一起。
  3. 移除键盘触发:删掉原有的键盘事件绑定,完全通过工具栏按钮执行数据处理。

注:如果需要自定义按钮图标,可给ProcessTool类添加default_icon属性,指向你的图标文件路径;不设置则使用Matplotlib默认按钮样式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:48:16