Python GUI ที่วาดจุดเมื่อคลิกที่พล็อต?

ลองใช้การวางแผนเชิงโต้ตอบก่อน ดังนั้นจึงยินดีรับความช่วยเหลือใดๆ

ฉันกำลังพยายามรับพล็อต matplotlib แบบโต้ตอบซึ่งมีการพล็อตจุดทุกครั้งที่คลิกเมาส์ จุดต่างๆ จะต้องลงจุด ณ ตำแหน่งที่คลิกและด้านบนของรูปภาพ ฉันคิดว่าฉันรู้วิธีทำเช่นนั้นแล้ว แต่ฉันสงสัยว่ามีวิธีง่ายๆ ในการเพิ่มปุ่ม "เลิกทำ" เพื่อที่ฉันจะได้ลบจุดสุดท้ายที่วางแผนไว้หากจำเป็นหรือไม่ ในแนวคิดเดียวกัน ฉันยังต้องการเพิ่มปุ่ม "รีเซ็ต" (เช่น ลบจุดทั้งหมด) และปุ่ม "บันทึก"

from matplotlib import pyplot as plt

def onclick(event):
    button=event.button
    x=event.xdata
    y=event.ydata

    if button==1: plt.plot(x,y,'ro')
    if button!=1: plt.plot(x,y,'bo')
    print 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%(
    event.button, event.x, event.y, event.xdata, event.ydata)

im = plt.imread('Picture1.png')
fig, ax=plt.subplots()
ax.imshow(im)
ax.autoscale(False)
cid = fig.canvas.mpl_connect('button_press_event', onclick)

plt.show()

person user2920100    schedule 25.10.2013    source แหล่งที่มา


คำตอบ (1)


คุณเพียงแค่ต้องเขียนตรรกะเพื่อทำมัน นี่เป็นเวอร์ชันที่ได้รับการแก้ไขเล็กน้อยของสิ่งที่ฉันใช้ (และเก็บไว้เพียงรายการเดียว) แต่ควรขยายสิ่งนี้ได้ง่ายเพื่อทำสิ่งที่คุณต้องการ

class clicker_class(object):
    def __init__(self, ax, pix_err=1):
        self.canvas = ax.get_figure().canvas
        self.cid = None
        self.pt_lst = []
        self.pt_plot = ax.plot([], [], marker='o',
                               linestyle='none', zorder=5)[0]
        self.pix_err = pix_err
        self.connect_sf()

    def set_visible(self, visible):
        '''sets if the curves are visible '''
        self.pt_plot.set_visible(visible)

    def clear(self):
        '''Clears the points'''
        self.pt_lst = []
        self.redraw()

    def connect_sf(self):
        if self.cid is None:
            self.cid = self.canvas.mpl_connect('button_press_event',
                                               self.click_event)

    def disconnect_sf(self):
        if self.cid is not None:
            self.canvas.mpl_disconnect(self.cid)
            self.cid = None

    def click_event(self, event):
        ''' Extracts locations from the user'''
        if event.key == 'shift':
            self.pt_lst = []
            return
        if event.xdata is None or event.ydata is None:
            return
        if event.button == 1:
            self.pt_lst.append((event.xdata, event.ydata))
        elif event.button == 3:
            self.remove_pt((event.xdata, event.ydata))

        self.redraw()

    def remove_pt(self, loc):
        if len(self.pt_lst) > 0:
            self.pt_lst.pop(np.argmin(map(lambda x:
                                          np.sqrt((x[0] - loc[0]) ** 2 +
                                                  (x[1] - loc[1]) ** 2),
                                          self.pt_lst)))

    def redraw(self):
        if len(self.pt_lst) > 0:
            x, y = zip(*self.pt_lst)
        else:
            x, y = [], []
        self.pt_plot.set_xdata(x)
        self.pt_plot.set_ydata(y)

        self.canvas.draw()

    def return_points(self):
        '''Returns the clicked points in the format the rest of the
        code expects'''
        return np.vstack(self.pt_lst).T

ax = gca()
cc = clicker_class(ax)
person tacaswell    schedule 25.10.2013