1

I have a class which allows the user to create a region using the mouse. Now I want to create multiple regions by appending objects to a list.

However, when I try to append it just runs once and I get 2 copies of the same region. It seems that both are running in parallel at the same time. Is there an easy workaround for this problem?

import numpy as np
import sys
import matplotlib.pyplot as plt
import matplotlib.path as mplPath
import matplotlib.image as mpimg

class create_region():

def __init__(self, img):
    if isinstance(img, np.ndarray):
         plt.imshow(img)
         fig = plt.gcf()
         fig.set_size_inches(12,9)
    else:
         print('Error: please include an image np.ndarray, create_region(img)')
         return

    self.img = img
    self.img_size = np.shape(img)
    self.line = None
    self.roicolor = (.415,1,.302) # Use neon green to stand out
    self.markersize = 4

    self.x_pts = []
    self.y_pts = []
    self.previous_pt = []
    self.start_point = []
    self.end_point = []
    self.fig = fig
    self.ax = plt.gca()

    self.__ID1 = self.fig.canvas.mpl_connect(
        'motion_notify_event', self.__motion_notify_callback)
    self.__ID2 = self.fig.canvas.mpl_connect(
        'button_press_event', self.__button_press_callback)

    if sys.flags.interactive:
        plt.show(block=False)
    else:
        plt.show()

def __motion_notify_callback(self, event):
    if event.inaxes:
        #ax = event.inaxes
        x, y = event.xdata, event.ydata
        # Move line around
        if (event.button == None or event.button == 1) and self.line != None: 
            self.line.set_data([self.previous_pt[0], x],
                               [self.previous_pt[1], y])
            self.fig.canvas.draw()

def __button_press_callback(self, event):
    if event.inaxes:
        x, y = event.xdata, event.ydata
        ax = event.inaxes
        # If you press the left button, single click
        if event.button == 1 and event.dblclick == False:  
            if self.line == None: # if there is no line, create a line
                self.line = plt.Line2D([x, x],
                                       [y, y],
                                       marker='o',
                                       color=self.roicolor,
                                       markersize = self.markersize)
                self.start_point = [x,y]
                self.previous_pt =  self.start_point
                self.x_pts=[x]
                self.y_pts=[y]

                ax.add_line(self.line)
                self.fig.canvas.draw()
                # add a segment
            else: # if there is a line, create a segment
                self.line = plt.Line2D([self.previous_pt[0], x],
                                       [self.previous_pt[1], y],
                                       marker = 'o',color=self.roicolor,
                                       markersize = self.markersize)
                self.previous_pt = [x,y]
                self.x_pts.append(x)
                self.y_pts.append(y)

                event.inaxes.add_line(self.line)
                self.fig.canvas.draw()
        # close the loop and disconnect
        elif ((event.button == 1 and event.dblclick==True) or
              (event.button == 3 and event.dblclick==False)) and self.line != None: 
            self.fig.canvas.mpl_disconnect(self.__ID1) #joerg
            self.fig.canvas.mpl_disconnect(self.__ID2) #joerg

            self.line.set_data([self.previous_pt[0],
                                self.start_point[0]],
                               [self.previous_pt[1],
                                self.start_point[1]])
            ax.add_line(self.line)
            self.fig.canvas.draw()
            self.line = None

            if sys.flags.interactive:
                pass
            else:
                #figure has to be closed so that code can continue
                plt.close(self.fig) 

# create zeros image
img=np.zeros((768,1024),dtype='uint8')

# try to append 2 different user regions to list
# seems both run simultaneously, returns 2 copies of 1 region   
M = []
for i in range(2):
    M.append(create_region(img))
JR_smith
  • 11
  • 1

0 Answers0