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

如何为Matplotlib交互式绘图工具栏添加信息弹窗按钮

Matplotlib自定义工具栏:添加显示绘图数据的按钮

Matplotlib的绘图工具栏支持自定义功能,官方提供了示例代码实现数据的隐藏/显示功能,示例界面如下:

绘图界面示例

官方示例代码

import matplotlib.pyplot as plt
from matplotlib.backend_tools import ToolBase, ToolToggleBase


plt.rcParams['toolbar'] = 'toolmanager'


class ListTools(ToolBase):
    """列出ToolManager控制的所有工具"""
    default_keymap = 'm'  # 快捷键
    description = '列出工具'

    def trigger(self, *args, **kwargs):
        print('_' * 80)
        fmt_tool = "{:12} {:45} {}".format
        print(fmt_tool('名称(ID)', '工具描述', '快捷键'))
        print('-' * 80)
        tools = self.toolmanager.tools
        for name in sorted(tools):
            if not tools[name].description:
                continue
            keys = ', '.join(sorted(self.toolmanager.get_tool_keymap(name)))
            print(fmt_tool(name, tools[name].description, keys))
        print('_' * 80)
        fmt_active_toggle = "{0!s:12} {1!s:45}".format
        print("激活的切换工具")
        print(fmt_active_toggle("分组", "激活项"))
        print('-' * 80)
        for group, active in self.toolmanager.active_toggle.items():
            print(fmt_active_toggle(group, active))


class GroupHideTool(ToolToggleBase):
    """显示指定gid的线条"""
    default_keymap = 'S'
    description = '按gid显示'
    default_toggled = True

    def __init__(self, *args, gid, **kwargs):
        self.gid = gid
        super().__init__(*args, **kwargs)

    def enable(self, *args):
        self.set_lines_visibility(True)

    def disable(self, *args):
        self.set_lines_visibility(False)

    def set_lines_visibility(self, state):
        for ax in self.figure.get_axes():
            for line in ax.get_lines():
                if line.get_gid() == self.gid:
                    line.set_visible(state)
        self.figure.canvas.draw()


fig = plt.figure()
plt.plot([1, 2, 3], gid='mygroup')
plt.plot([2, 3, 4], gid='unknown')
plt.plot([3, 2, 1], gid='mygroup')

# 添加自定义工具
fig.canvas.manager.toolmanager.add_tool('List', ListTools)
fig.canvas.manager.toolmanager.add_tool('Show', GroupHideTool, gid='mygroup')

# 将现有工具添加到新分组`foo`
fig.canvas.manager.toolbar.add_tool('zoom', 'foo')

# 移除前进按钮
fig.canvas.manager.toolmanager.remove_tool('forward')

# 将自定义工具添加到导航分组的指定位置
fig.canvas.manager.toolbar.add_tool('Show', 'navigation', 1)

plt.show()

需求:添加按钮点击后在新窗口显示绘图数据文本

要实现点击工具栏按钮后弹出新窗口展示绘图数据的文本信息,可以基于ToolBase自定义工具类,结合Matplotlib默认后端的Tkinter库创建窗口。

实现方案

  1. 自定义继承ToolBase的工具类,在trigger方法中创建新窗口并提取、格式化绘图数据。
  2. 使用Tkinter的滚动文本组件展示数据,适配大量数据的查看需求。
  3. 将自定义工具添加到工具栏的指定位置。

完整示例代码

import matplotlib.pyplot as plt
from matplotlib.backend_tools import ToolBase, ToolToggleBase
import tkinter as tk
from tkinter import scrolledtext

plt.rcParams['toolbar'] = 'toolmanager'

# 保留官方示例的自定义工具
class ListTools(ToolBase):
    """列出ToolManager控制的所有工具"""
    default_keymap = 'm'  # 快捷键
    description = '列出工具'

    def trigger(self, *args, **kwargs):
        print('_' * 80)
        fmt_tool = "{:12} {:45} {}".format
        print(fmt_tool('名称(ID)', '工具描述', '快捷键'))
        print('-' * 80)
        tools = self.toolmanager.tools
        for name in sorted(tools):
            if not tools[name].description:
                continue
            keys = ', '.join(sorted(self.toolmanager.get_tool_keymap(name)))
            print(fmt_tool(name, tools[name].description, keys))
        print('_' * 80)
        fmt_active_toggle = "{0!s:12} {1!s:45}".format
        print("激活的切换工具")
        print(fmt_active_toggle("分组", "激活项"))
        print('-' * 80)
        for group, active in self.toolmanager.active_toggle.items():
            print(fmt_active_toggle(group, active))

class GroupHideTool(ToolToggleBase):
    """显示指定gid的线条"""
    default_keymap = 'S'
    description = '按gid显示'
    default_toggled = True

    def __init__(self, *args, gid, **kwargs):
        self.gid = gid
        super().__init__(*args, **kwargs)

    def enable(self, *args):
        self.set_lines_visibility(True)

    def disable(self, *args):
        self.set_lines_visibility(False)

    def set_lines_visibility(self, state):
        for ax in self.figure.get_axes():
            for line in ax.get_lines():
                if line.get_gid() == self.gid:
                    line.set_visible(state)
        self.figure.canvas.draw()

# 新增:显示绘图数据的自定义工具
class ShowDataTool(ToolBase):
    """在新窗口显示绘图数据详情"""
    default_keymap = 'd'  # 快捷键
    description = '显示绘图数据'

    def trigger(self, *args, **kwargs):
        # 创建新窗口
        data_window = tk.Toplevel()
        data_window.title("绘图数据详情")
        data_window.geometry("600x400")

        # 创建带滚动的文本框
        text_area = scrolledtext.ScrolledText(data_window, wrap=tk.WORD, width=70, height=20)
        text_area.pack(padx=10, pady=10, fill=tk.BOTH, expand=True)

        # 提取并格式化所有绘图数据
        data_text = "绘图数据详情:\n" + "-"*50 + "\n"
        for ax_idx, ax in enumerate(self.figure.get_axes(), 1):
            data_text += f"\n坐标轴 {ax_idx}:\n"
            for line_idx, line in enumerate(ax.get_lines(), 1):
                x_data = line.get_xdata()
                y_data = line.get_ydata()
                gid = line.get_gid() or "无gid"
                label = line.get_label() or "无标签"
                data_text += f"线条 {line_idx} | 标签: {label} | gid: {gid}\n"
                data_text += f"X数据: {x_data}\n"
                data_text += f"Y数据: {y_data}\n"
                data_text += "-"*30 + "\n"

        # 插入数据并设置只读
        text_area.insert(tk.INSERT, data_text)
        text_area.config(state=tk.DISABLED)

# 创建绘图
fig = plt.figure()
plt.plot([1, 2, 3], gid='mygroup', label='上升线条')
plt.plot([2, 3, 4], gid='unknown', label='持续上升')
plt.plot([3, 2, 1], gid='mygroup', label='下降线条')
plt.legend()

# 添加所有自定义工具
fig.canvas.manager.toolmanager.add_tool('List', ListTools)
fig.canvas.manager.toolmanager.add_tool('Show', GroupHideTool, gid='mygroup')
# 添加显示数据工具到导航分组的第3个位置(索引从0开始)
fig.canvas.manager.toolmanager.add_tool('ShowData', ShowDataTool)
fig.canvas.manager.toolbar.add_tool('ShowData', 'navigation', 2)

# 移除前进按钮
fig.canvas.manager.toolmanager.remove_tool('forward')

plt.show()

关键说明

  • 自定义工具类:ShowDataTool继承ToolBase,trigger方法是按钮点击后的执行逻辑,负责创建窗口和展示数据。
  • 数据提取:通过line.get_xdata()、line.get_ydata()获取线条的坐标数据,同时可提取gid、标签等附加信息。
  • 窗口组件:使用scrolledtext.ScrolledText实现带滚动的文本展示,避免数据过长无法完全显示。
  • 工具栏集成:通过add_tool方法将自定义工具添加到指定分组,控制其在工具栏中的位置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 19:54:58