views:

60

answers:

2

Hi, how do I plot an area around a set of points on a map in R? e.g.

map('world')
map.axes()
p <- matrix(c(50, 50, 80, 100, 70, 40, 25, 60), ncol=2) # make some points
points(p, pch=19, col="red")

polygon(p, col="blue")

... which gives me a polygon with a vertex at each of the points, but it looks rather crappy. Is there any way to "smooth" the polygon into some sort of curve?

A: 

Here's one way, draw the polygon and make it as pretty as you like. This really has nothing to do with areas on maps, more about how you generate the vertices of your polygon.

    library(maps)
    p <- matrix(c(50, 50, 80, 100, 70, 40, 25, 60), ncol=2)     
    plot(p, pch = 16, col = "red", cex = 3, xlim = range(p[,1]) + c(-10,10), ylim = range(p[,2]) + c(-5, 5))
    map(add = TRUE)
    #click until happy, right-click "stop" to finish
    p <- locator(type = "l")
    map()
    polygon(cbind(p$x, p$y), col = "blue")

Otherwise you could interpolate intermediate vertices and smooth them somehow, and in the context of a lon/lat map maybe with use reprojection to get more realistic line segments - but depends on your purpose.

mdsumner
A: 

One option is to make a polygon bounded by a Bézier curve, using the bezier function in the Hmisc package. However I cannot get the start/end point to join up neatly. For example:

## make some points
p <- matrix(c(50, 50, 80, 100, 70, 40, 25, 60), ncol=2)
## add the starting point to the end
p2 <- cbind(1:5,p[c(1:4,1),])
## linear interpolation between these points                            
t.coarse <- seq(1,5,0.05)
x.coarse <- approx(p2[,1],p2[,2],xout=t.coarse)$y
y.coarse <- approx(p2[,1],p2[,3],xout=t.coarse)$y
## create a Bezier curve                                           
library(Hmisc)
bz <- bezier(x.coarse,y.coarse)
library(maps)
map('world')
map.axes()
polygon(bz$x,bz$y, col=rgb(0,0,1,0.5),border=NA)
nullglob