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

如何追踪matplotlib中ginput()函数的鼠标点击次数?

关于matplotlib.pyplot.ginput()的点击次数记录与点击区分问题

1. 保存实际点击次数

plt.ginput()返回的pts长度是最终保留的点数量,右键会移除之前的点,因此无法直接通过len(pts)获取总点击次数。要记录真实点击次数,需要手动监听鼠标点击事件:

实现代码

# 允许用户点击添加标签,将点击位置存储为名为pts的元组列表
tellme('您将定义目标标签,点击开始')
plt.waitforbuttonpress()

while True:
    pts = []
    num_clicks = 0  # 初始化总点击计数器
    click_history = []  # 记录每次点击的按键类型

    # 鼠标点击事件处理函数
    def on_click(event):
        nonlocal num_clicks, click_history
        num_clicks += 1
        click_history.append(event.button)  # 1=左键, 2=中键, 3=右键

    # 注册事件监听
    cid = plt.gcf().canvas.mpl_connect('button_press_event', on_click)

    tellme('用鼠标选择目标位置。右键可移除最近添加的点。完成后,使用中键终止输入。')
    pts = np.asarray(plt.ginput(-1, timeout=-1)) #ginput返回点击的(x, y)坐标列表(元组列表)

    # 取消事件监听
    plt.gcf().canvas.mpl_disconnect(cid)

    print(f'已选点:{pts}')
    print(f'总点击次数:{num_clicks}')

    # 区分直接中键点击与右键点击后再中键点击
    is_right_then_middle = False
    if len(click_history) >= 2:
        if click_history[-2] == 3 and click_history[-1] == 2:
            is_right_then_middle = True

    tellme('是否满意?按回车键确认,点击鼠标重新选择')

    if plt.waitforbuttonpress():
        # 若pts为空,则使用原始标签作为清理后的标签
        if len(pts) == 0 and len(scan.raw_labels_polar) > 1:
            pts = scan.raw_labels_polar
        # 若pts为空,但并非用户想要使用原始标签,而是仅生成空csv
        if len(pts) == 0 and len(scan.raw_labels_polar) == 1 and num_clicks > 0:
            pts = []
        
        labels.list_to_csv(pts, scan.scan_number, save_to)  # 将新的元组列表保存为路径下的csv文件

        break

说明

  • num_clicks会统计所有鼠标按键的点击次数,包括左键(添加点)、右键(移除点)、中键(终止输入)
  • 如果需要单独统计不同按键的点击次数,可以扩展事件处理函数,分别维护left_clicks、right_clicks、middle_clicks变量

2. 区分直接中键点击与右键后中键点击

通过click_history列表记录每次点击的按键类型,即可精准判断点击顺序:

  • 直接中键点击:click_history仅包含一个元素2
  • 右键后中键点击:click_history最后两个元素为3(右键)和2(中键)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 12:34:51