Matplotlib: dibuje un área de selección con la forma de un rectángulo con el mouse

Quiero poder dibujar un área de selección en un gráfico de matplotlib con un evento de mouse. No encontré información sobre cómo hacerlo con python.

Al final, quiero poder dibujar una región de interés con mi mouse en un mapa creado con el mapa base de matplotlib y recuperar las coordenadas de las esquinas.

¿Alguien tiene una idea, ejemplo, referencias?

Gracias,

Greg

class Annotate(object): def __init__(self): self.ax = plt.gca() self.rect = Rectangle((0,0), 1, 1, facecolor='None', edgecolor='green') self.x0 = None self.y0 = None self.x1 = None self.y1 = None self.ax.add_patch(self.rect) self.ax.figure.canvas.mpl_connect('button_press_event', self.on_press) self.ax.figure.canvas.mpl_connect('button_release_event', self.on_release) self.ax.figure.canvas.mpl_connect('motion_notify_event', self.on_motion) def on_press(self, event): print 'press' self.x0 = event.xdata self.y0 = event.ydata self.x1 = event.xdata self.y1 = event.ydata self.rect.set_width(self.x1 - self.x0) self.rect.set_height(self.y1 - self.y0) self.rect.set_xy((self.x0, self.y0)) self.rect.set_linestyle('dashed') self.ax.figure.canvas.draw() def on_motion(self,event): if self.on_press is True: return self.x1 = event.xdata self.y1 = event.ydata self.rect.set_width(self.x1 - self.x0) self.rect.set_height(self.y1 - self.y0) self.rect.set_xy((self.x0, self.y0)) self.rect.set_linestyle('dashed') self.ax.figure.canvas.draw() def on_release(self, event): print 'release' self.x1 = event.xdata self.y1 = event.ydata self.rect.set_width(self.x1 - self.x0) self.rect.set_height(self.y1 - self.y0) self.rect.set_xy((self.x0, self.y0)) self.rect.set_linestyle('solid') self.ax.figure.canvas.draw() print self.x0,self.x1,self.y0,self.y1 return [self.x0,self.x1,self.y0,self.y1] 

Matplotlib proporciona su propio RectangleSelector . Hay un ejemplo en la página matplotlib, que puede adaptar a sus necesidades.

Una versión simplificada se vería así:

 import matplotlib.pyplot as plt import numpy as np from matplotlib.widgets import RectangleSelector xdata = np.linspace(0,9*np.pi, num=301) ydata = np.sin(xdata) fig, ax = plt.subplots() line, = ax.plot(xdata, ydata) def line_select_callback(eclick, erelease): x1, y1 = eclick.xdata, eclick.ydata x2, y2 = erelease.xdata, erelease.ydata rect = plt.Rectangle( (min(x1,x2),min(y1,y2)), np.abs(x1-x2), np.abs(y1-y2) ) ax.add_patch(rect) rs = RectangleSelector(ax, line_select_callback, drawtype='box', useblit=False, button=[1], minspanx=5, minspany=5, spancoords='pixels', interactive=True) plt.show() 

Aquí hay un pequeño ejemplo que muestra cómo usar el mouse para dibujar un rectángulo en un gráfico de matplotlib.

 import matplotlib.pyplot as plt from matplotlib.patches import Rectangle class Annotate(object): def __init__(self): self.ax = plt.gca() self.rect = Rectangle((0,0), 1, 1) self.x0 = None self.y0 = None self.x1 = None self.y1 = None self.ax.add_patch(self.rect) self.ax.figure.canvas.mpl_connect('button_press_event', self.on_press) self.ax.figure.canvas.mpl_connect('button_release_event', self.on_release) def on_press(self, event): print 'press' self.x0 = event.xdata self.y0 = event.ydata def on_release(self, event): print 'release' self.x1 = event.xdata self.y1 = event.ydata self.rect.set_width(self.x1 - self.x0) self.rect.set_height(self.y1 - self.y0) self.rect.set_xy((self.x0, self.y0)) self.ax.figure.canvas.draw() a = Annotate() plt.show()