绘制2D人口分布的热图(或类似)

时间:2016-07-29 11:46:48

标签: r interpolation contour r-raster bilinear-interpolation

我想知道如何绘制人口比例的图像(pop.prop) 在这些地方(x和y),我可以清楚地看到人口分布?

数据如下所示:

pts.pr = pts.cent[pts.cent$PIDS==3, ]    
pop = rnorm(nrow(pts.pr), 0, 1)    
pop.prop = exp(pop)/sum(exp(pop))    
pts.pr.data = as.data.frame(cbind(pts.pr@coords, cbind(pop.prop)))

            x        y    pop.prop
3633 106.3077 38.90931 0.070022855    
3634 106.8077 38.90931 0.012173106    
3756 106.3077 38.40931 0.039693085    
3878 105.8077 37.90931 0.034190747    
3879 106.3077 37.90931 0.057981214    
3880 106.8077 37.90931 0.089484103    
3881 107.3077 37.90931 0.026018622    
3999 104.8077 37.40931 0.008762790    
4000 105.3077 37.40931 0.030027889    
4001 105.8077 37.40931 0.038175671    
4002 106.3077 37.40931 0.017137084    
4003 106.8077 37.40931 0.038560394    
4123 105.3077 36.90931 0.021653256    
4124 105.8077 36.90931 0.107731536    
4125 106.3077 36.90931 0.036780336    
4247 105.8077 36.40931 0.269878770    
4248 106.3077 36.40931 0.004316260    
4370 105.8077 35.90931 0.003061392    
4371 106.3077 35.90931 0.050781007    
4372 106.8077 35.90931 0.034190670    
4494 106.3077 35.40931 0.009379213

x是经度,y是纬度。

1 个答案:

答案 0 :(得分:1)

我认为我找到了三种可能的解决方案/方法。

首先是数据:

pop <- read.table(header=TRUE, 
text="
       x        y        prop
106.3077 38.90931 0.070022855    
106.8077 38.90931 0.012173106    
106.3077 38.40931 0.039693085    
105.8077 37.90931 0.034190747    
106.3077 37.90931 0.057981214    
106.8077 37.90931 0.089484103    
107.3077 37.90931 0.026018622    
104.8077 37.40931 0.008762790    
105.3077 37.40931 0.030027889    
105.8077 37.40931 0.038175671    
106.3077 37.40931 0.017137084    
106.8077 37.40931 0.038560394    
105.3077 36.90931 0.021653256    
105.8077 36.90931 0.107731536    
106.3077 36.90931 0.036780336    
105.8077 36.40931 0.269878770    
106.3077 36.40931 0.004316260    
105.8077 35.90931 0.003061392    
106.3077 35.90931 0.050781007    
106.8077 35.90931 0.034190670    
106.3077 35.40931 0.009379213")

第一种方法类似于我在上面的评论中提到的方法,除了使用符号颜色而不是符号大小来表示种群大小:

# I might be overcomplicating things a bit with this colour function

cfun <- function(x, bias=2) {
    x <- (x-min(x))/(max(x)-min(x))
    xcol <- colorRamp(c("lightyellow", "orange", "red"), bias=bias)(x)
    rgb(xcol, maxColorValue=255)
}

# It is possible to also add a colour key, but I didn't bother

plot(pop$x, pop$y, col=cfun(pop$prop), cex=4, pch=20,
    xlab="Lon.", ylab="Lat.", main="Population Distribution")

enter image description here

第二种方法依赖于将lon-lat-value格式转换为常规栅格,然后可以将其表示为热图:

library(raster)
e <- extent(pop[,1:2])

# this simple method of finding the correct number of rows and
# columns by counting the number of unique coordinate values in each
# dimension works in this case because there are no 'islands'
# (or if you wish, just one big 'island'), and the points are already
# regularly spaced.

nun <- function(x) { length(unique(x))}

r <- raster(e, ncol=nun(pop$x), nrow=nun(pop$y))

x <- rasterize(pop[, 1:2], r, pop[,3], fun=sum)
as.matrix(x)

cpal <- colorRampPalette(c("lightyellow", "orange", "red"), bias=2)

plot(x, col=cpal(200),
    xlab="Lon.", ylab="Lat.", main="Population Distribution")

enter image description here

从这里解除:How to make RASTER from irregular point data without interpolation

另外值得一试:creating a surface from "pre-gridded" points。 (使用reshape2代替raster

第三种方法依赖于插值来绘制填充的轮廓:

library(akima)

# interpolation
pop.int <- interp(pop$x, pop$y,  pop$prop)

filled.contour(pop.int$x, pop.int$y, pop.int$z,
    color.palette=cpal,
    xlab="Longitude", ylab="Latitude",
    main="Population Distribution",
    key.title = title(main="Proportion", cex.main=0.8))

enter image description here

从这里抓获:Plotting contours on an irregular grid