1

In a scatterplot matrix, I want to draw a region of interest(ROI) and print the points that are contained in that region. For the time being, I can draw regions in the subplots but I do not know how to get and print the points that are contained in the region. A region is drawn, when the shift key and the left mouse button are hold pressed. The region is closed by clicking on the right mouse button, while the shift is hold pressed. Any suggestions about how the printing of the points inside the ROI( a functionality similar to LassoSelector demo) will be appreciated. Thanks in advance!!

Here is the code:

 from pylab import *


 class ROI:

    def __init__(self, axes, fig):
        self.previous_point = []
        self.start_point = []
        self.end_point = []
        self.line = None    

        self.fig =  fig
        self.fig.canvas.draw()

    def motion_notify_callback(self, event):
        if event.inaxes: 
            axes = event.inaxes
            x, y = event.xdata, event.ydata
            if event.button == None and self.line != None and event.key == 'shift': # #Move line around
                self.line.set_data([self.previous_point[0], x],
                                   [self.previous_point[1], y])
                self.fig.canvas.draw()
         elif event.button == 1 and event.key == 'shift': # Free Hand Drawing
                    line = Line2D([self.previous_point[0], x],
                                  [self.previous_point[1], y])
                    axes.add_line(line)
                    self.previous_point = [x, y]
                    self.fig.canvas.draw()


    def button_press_callback(self, event):
        if event.inaxes: 
            x, y = event.xdata, event.ydata
            axes = event.inaxes
            if (event.key == 'shift') and (event.button == 1):  # If you press the right button
                    if self.line == None: # if there is no line, create a line
                        self.line = Line2D([x,  x],
                                           [y, y],
                                           marker = 's')
                        self.start_point = [x,y]
                        self.previous_point =  self.start_point
                        axes.add_line(self.line)
                        self.fig.canvas.draw()
                    # add a segment
                    else: # if there is a line, create a segment
                        self.line = Line2D([self.previous_point[0], x],
                                           [self.previous_point[1], y],
                                           marker = 'o')
                        self.previous_point = [x,y]
                        event.inaxes.add_line(self.line)
                        self.fig.canvas.draw()

            if (event.button == 3) and (event.key == 'shift') and (self.line != None): # close the loop
                        self.line.set_data([self.previous_point[0], self.start_point[0]],
                                           [self.previous_point[1], self.start_point[1]])                       
                        axes.add_line(self.line)
                        self.fig.canvas.draw()
                        self.line = None




def main():
    data = np.random.rand(100,4)
    plt.close("all")
    x, y = data[:, 0], data[:, 1]
    x1, y1 = data[:,2], data[:, 3]
    fig, axes = plt.subplots(ncols=2, nrows=1)
    for ax, marker in zip(axes.flat, ['o', 'o']):



        axes.flat[0].plot(x, y, 'r',  ls='', marker=marker, picker=3)

        axes.flat[1].plot(x, x1,'r', ls='', marker=marker, picker=3)

        cursor = ROI(ax, fig)

    #axes.set_title(" shift+left click: line segment       shift+left pressed: doodle        shift+right click: close region")

    fig.canvas.mpl_connect('motion_notify_event', cursor.motion_notify_callback)
    fig.canvas.mpl_connect('button_press_event', cursor.button_press_callback)
    show()

if __name__ == "__main__":
    main()   
user_jt
  • 259
  • 4
  • 15
  • 1
    you can use the approach of [this answer](http://stackoverflow.com/a/22357685/832621) or some of the other answers to identify the equation of the region, then you have to go further to check which points are inside – Saullo G. P. Castro Mar 22 '14 at 19:37

1 Answers1

0

I think matplotlib has a nice function called matplotlib.nxutils for checking if points are inside polygon or not.

http://matplotlib.org/faq/howto_faq.html#test-whether-a-point-is-inside-a-polygon

You can convert your ROI into polygon and apply nx.points_inside_poly.

(Edit) matplotlib.nxutils has been depreciated and repclaed with matplotlib.path.Path.contains_points. I did not know that. Thanks for head up. Here's a small snippet that uses Path.contains_points.

from pylab import *
from matplotlib.path import Path
import matplotlib.patches as patches

data = np.random.rand(100,4)

verts = [(0.3, 0.7), (0.3, 0.3), (0.7, 0.3), (0.7, 0.7)]

path1 = Path(verts)
index = path1.contains_points(data[:,:2])

print data[index, :2]

plot(data[:,0],data[:,1], 'b.')
patch = patches.PathPatch(path1, facecolor='orange', lw=2)
gca().add_patch(patch)
plot(data[index,0], data[index,1], 'r.')
show()
otterb
  • 2,660
  • 2
  • 29
  • 48
  • I think that this function has been replaced by `contains_points`. Although, it is a step towards what I want to do, I do not think that I can print the values of a point with these functions, but only a boolean array which prints True or False , if the points are in the polygon or not. – user_jt Mar 23 '14 at 00:25
  • how about slicing using bool array like data[result_bool]? – otterb Mar 23 '14 at 09:33
  • 1
    To add about ROI drawing, I just learned about matplotlib.widgets.LassoSelector. sample: http://matplotlib.org/examples/widgets/lasso_selector_demo.html – otterb Apr 22 '14 at 15:35
  • I used the other matplotlib example the `Lasso` function for the drawing of a region. But, I have a problem. It seems that the Lasso works correctly only when the function is called for the last time in my code(maybe it overwrites the previous calls). Do you have any idea why something like that happens? I describe my problem in the update section of this question http://stackoverflow.com/questions/22355435/how-to-pick-a-point-in-a-subplot-and-highlight-it-in-adjacent-subplots-in-matplo . – user_jt Apr 25 '14 at 23:36