首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

使用 Matplotlib 在座標系中互動式繪製矩形

     編輯:更多程式設計知識

Matplotlib 不僅能繪製靜態圖表,透過事件處理機制還能實現互動式繪圖。本文示範如何利用 matplotlib.patches.Rectangle 搭配滑鼠事件(button_press_event、button_release_event),在座標系中以拖曳方式畫出矩形,並即時更新顯示。

核心原理

  1. 建立一個 Rectangle 物件並加入 Axes(ax.add_patch)。
  2. 綁定滑鼠按下事件:記錄起始座標 (x0, y0)。
  3. 綁定滑鼠釋放事件:記錄結束座標 (x1, y1),計算寬高並更新 Rectangle 的幾何屬性。
  4. 呼叫 canvas.draw() 重繪畫布。

完整可執行代碼

import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle

class RectangleDrawer:
    """互動式矩形繪製器"""
    def __init__(self):
        self.fig, self.ax = plt.subplots()
        self.ax.set_title('拖曳滑鼠繪製矩形,關閉視窗結束')
        self.ax.set_xlim(0, 10)
        self.ax.set_ylim(0, 10)

        # 初始矩形(寬高為 0,不可見)
        self.rect = Rectangle((0, 0), 0, 0,
                              edgecolor='red', facecolor='none', linewidth=2)
        self.ax.add_patch(self.rect)

        self.x0 = self.y0 = None
        self.cid_press = self.fig.canvas.mpl_connect('button_press_event', self.on_press)
        self.cid_release = self.fig.canvas.mpl_connect('button_release_event', self.on_release)

    def on_press(self, event):
        if event.inaxes != self.ax:
            return
        self.x0, self.y0 = event.xdata, event.ydata
        # 重置矩形到起點,寬高歸零
        self.rect.set_xy((self.x0, self.y0))
        self.rect.set_width(0)
        self.rect.set_height(0)
        self.fig.canvas.draw()

    def on_release(self, event):
        if event.inaxes != self.ax or self.x0 is None:
            return
        x1, y1 = event.xdata, event.ydata
        # 計算寬高(允許負值,自動修正)
        w, h = x1 - self.x0, y1 - self.y0
        self.rect.set_width(w)
        self.rect.set_height(h)
        self.fig.canvas.draw()
        print(f"矩形座標:({self.x0:.2f}, {self.y0:.2f}) 寬高:({w:.2f}, {h:.2f})")

    def show(self):
        plt.show()

if __name__ == '__main__':
    drawer = RectangleDrawer()
    drawer.show()

進階擴充:即時拖曳預覽

若希望在拖曳過程中即時看到矩形變化,可改綁定 motion_notify_event:

self.cid_motion = self.fig.canvas.mpl_connect('motion_notify_event', self.on_motion)

def on_motion(self, event):
    if event.inaxes != self.ax or self.x0 is None:
        return
    w, h = event.xdata - self.x0, event.ydata - self.y0
    self.rect.set_width(w)
    self.rect.set_height(h)
    self.fig.canvas.draw_idle()  # 非阻塞重繪,效能更好

常見應用場景

  • ROI 選取:影像處理中框選感興趣區域。
  • 資料標註:為物件偵測、分割任務產生 bounding box 標籤。
  • 互動式儀表板:使用者框選區域後觸發後續分析(縮放、統計、導出)。

注意事項

  • 座標系為資料座標(event.xdata/ydata),非像素座標;若需像素座標請用 event.x/y。
  • 若在 Jupyter Notebook 中執行,請改用 %matplotlib widget 或 %matplotlib qt 後端,否則事件迴圈無法正常運作。
  • 若需支援多個矩形,可在類別中維護一個列表,並在釋放事件中建立新的 Rectangle 物件。

透過不到 50 行代碼,即可擁有一個可互動的矩形繪製工具,作為更複雜標註系統的基礎模組非常合適。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved