Polygon-like interactive selection of plotted points
Clint, Not sure why I would be surprised (unless you meant Florian), as I have not actually used these functions. I simply referenced them as part of the search to assist Florian. :-) However, your reply did make me curious, so I installed the 'splancs' package along with 'sp' as a dependency. Just for reference, this is on R 2.3.0 under FC4 compiled from source. I did run Roger's code, the result of which is attached here as a PDF, which should come through the list. While my 7 sided polygon is likely different than yours, the result seems to be the same. That is, only 3 of the vertices are considered within the boundary and this is unaffected by the use of the 'bound' argument to input(). The 'bound' argument in inout() does need to be set to TRUE in order for the boundary points to be considered 'within' the polygon. Otherwise, with the default NULL, the assignment is arbitrary. Thus, Roger's code, which has the default NULL value in the call to inout(), could reasonably result in your/our finding. One quick guess here might be that the values returned by getpoly() are not the exact center points of the original dataset, but are the x,y coords of where the clicks occur. There is a "hand-to-eyeball-coordination" margin of error relative to the actual coords. Thus, the coordinate values returned by this approach are very slightly outside the polygon and not picked up by inout() as being on the boundary. I tried the followingm using identify() instead: library(splancs) set.seed(20060426) xy <- cbind(x=runif(100), y=runif(100)) plot(xy) # Select the SAME 7 vertices here pts <- identify(xy, n = 7) # These are the row indices into 'xy' # for the coords of the vertices > pts [1] 18 44 51 61 73 89 91 > io <- inout(xy, xy[pts, ], bound = TRUE, quiet = FALSE) Points on boundary: [1] 18 44 51 61 73 89 91 Note that the same indices of the points are now returned by inout() as were selected when using identify(). Note also the setting of 'bound = TRUE'. You can now use: points(xy[io,], pch=16, col="blue") to draw BOTH the points inside the polygon and the boundary points as well. Thus, this would support my thoughts above, since identify() uses a 'tolerance' argument to identify the actual data points closest the mouse click, much like all.equal() does with respect to floating point comparisons. In a case like this, identify() would seem to be a better choice relative to selecting the polygon boundary if one wants the exact boundary points to be considered in or out of the polygon. HTH, Marc Schwartz
On Wed, 2006-04-26 at 13:01 -0700, Clint Bowman wrote:
Roger, Just for fun I tried your script--nothing wrong with the script, but I created a seven sided polygon by clicking on seven points and letting getpoly complete the figure. At the end I notice that only three of the seven vertices are coded as being inside the ploygon (the blue points.) I'd send you a screen dump but I haven't gotten xwd to work with Exceed. Also I haven't checked any docs to see whether this is a known problem but suspect that Marc could be surprised by the behavior. Clint
On Wed, 26 Apr 2006, Roger Bivand wrote:
On Wed, 26 Apr 2006, Marc Schwartz (via MN) wrote:
On Wed, 2006-04-26 at 18:13 +0100, Florian Nigsch wrote:
[Please CC me for all replies, since I am not currently subscribed to the list.] Hi all, I have the following problem/question: Imagine you have a two- dimensional plot, and you want to select a number of points, around which you could draw a polygon. The points of the polygon are defined by clicking in the graphics window (locator()/identify()), all points inside the polygon are returned as an object. Is something like this already implemented? Thanks a lot in advance, Florian
I don't know if anyone has created a single function do to this (though
it is always possible).
However, using:
RSiteSearch("points inside polygon")
brings up several function hits that, if put together with the above
interactive functions, could be used to do what you wish. That is, input
the matrix of x,y coords of the interactively selected polygon and the
x,y coords of the underlying points set to return the points inside or
outside the polygon boundaries.
This sequence from the splancs package should do it: library(splancs) set.seed(20060426) xy <- cbind(x=runif(100), y=runif(100)) plot(xy) poly <- getpoly() # this gets the polygon on-screen plot(xy) polygon(poly) io <- inout(xy, poly) # this returns a logical vector for points in the polygon points(xy[io,], pch=16, col="blue") Roger
Just as an FYI, you might also want to look at ?chull, which is in the base R distribution and returns the set of points on the convex hull of the underlying point set. This is to some extent, the inverse of what you wish to do. HTH, Marc Schwartz
-------------- next part -------------- A non-text attachment was scrubbed... Name: poly.pdf Type: application/pdf Size: 9524 bytes Desc: not available Url : https://stat.ethz.ch/pipermail/r-help/attachments/20060426/223f57fc/attachment.pdf