tylerthemiler
tylerthemiler

Reputation: 5746

Pause execution during button_press_event in matplotlib

I am trying to plot a polygon of user clicks and render them over a matplotlib canvas:

def helperClick(self, clickEvent):
        self.lastXClick = clickEvent.x 
        self.lastYClick = clickEvent.y
        self.lastButtonClick = clickEvent.button

def measurePoly(self):

    self.lastButtonClick = None
    cid = self.ui.canvas2.mpl_connect('button_press_event', self.helperClick)

    #Exit render loop on right click
    while self.lastButtonClick != 3:
       print('waiting')
       if self.lastButtonClick == 1:
           #Eventually render polygon on click of 1
           print('clicked')

    self.ui.canvas2.mpl_disconnect(cid)

    #do more stuff with polygon data

I am just trying to "wait" for user clicks, do something on a user click, then continue down the function on a left-click. However, my infinite loop freezes up python and crashes. I know this is a bad way to do this (clearly as it doesn't work :P) but I am not sure how to properly do this.

Thanks,

tylerthemiler

Upvotes: 0

Views: 1087

Answers (1)

Joe Kington
Joe Kington

Reputation: 284652

It sounds like you're trying to manually run the "mainloop" in your own code?

The whole point of using callback functions is that you let the gui toolkit run its own mainloop (in this case, it's entered when you call show).

Here's a very simple example of something along the lines of what you're trying to do.

It adds verticies when you left-click on the (initially blank) plot, and then draws the corresponding polygon when you right click. Nothing is drawn until you right-click (It's not too hard to draw the polygon while you're adding points by left-clicking, but doing it efficiently in matplotlib is a bit verbose).

import matplotlib.pyplot as plt

class Plot(object):
    def __init__(self):
        self.poly = []
        self.fig, self.ax = plt.subplots()
        self.ax.axis([0, 10, 0, 10])
        self.fig.canvas.mpl_connect('button_press_event', self.on_click)

        plt.show()

    def on_click(self, event):
        if event.button == 1:
            self.poly.append((event.xdata, event.ydata))
        elif event.button == 3:
            self.draw_poly()

    def draw_poly(self):
        self.ax.fill(*zip(*self.poly))
        self.poly = []
        self.fig.canvas.draw()

Plot()

Upvotes: 2

Related Questions