我对ggplot比较陌生,所以如果我的一些问题很简单或根本无法解决,请原谅我。
我想要做的是生成一个国家的“热图”,其中形状的填充是连续的。此外,我的国家形状为.RData
。我使用hadley wickham's script将我的SpatialPolygon数据转换为数据框。我的数据框的long和lat数据现在看起来像这样
head(my_df)
long lat group
6.527187 51.87055 0.1
6.531768 51.87206 0.1
6.541202 51.87656 0.1
6.553331 51.88271 0.1
这个长/拉数据描绘了德国的轮廓。这里省略了数据框的其余部分,因为我认为不需要它。对于某些长/纬度点,我还有第二个数据帧。这看起来像这样
my_fixed_points
long lat value
12.817 48.917 0.04
8.533 52.017 0.034
8.683 50.117 0.02
7.217 49.483 0.0542
我现在要做的是,根据位于该点一定距离内的所有固定点的平均值,为地图的每个点着色。这样我就可以得到整个国家地图的(几乎)连续着色。 到目前为止我所拥有的是用ggplot2绘制的国家地图
ggplot(my_df,aes(long,lat)) + geom_polygon(aes(group=group), fill="white") +
geom_path(color="white",aes(group=group)) + coord_equal()
我的第一个想法是生成位于已绘制的地图内的点,然后计算每个生成的点my_generated_point
的值,如此
value_vector <- subset(my_fixed_points,
spDistsN1(cbind(my_fixed_points$long, my_fixed_points$lat),
c(my_generated_point$long, my_generated_point$lat), longlat=TRUE) < 50,
select = value)
point_value <- mean(value_vector)
我还没有找到一种方法来产生这些点。就像整个问题一样,我甚至不知道是否有可能以这种方式解决。我现在的问题是,是否存在生成这些点的方法和/或是否有另一种方法来解决问题。
解决方案
感谢保罗,我几乎得到了我想要的东西。以下是荷兰的样本数据示例。
library(ggplot2)
library(sp)
library(automap)
library(rgdal)
library(scales)
#get the spatial data for the Netherlands
con <- url("http://gadm.org/data/rda/NLD_adm0.RData")
print(load(con))
close(con)
#transform them into the right format for autoKrige
gadm_t <- spTransform(gadm, CRS=CRS("+proj=merc +ellps=WGS84"))
#generate some random values that serve as fixed points
value_points <- spsample(gadm_t, type="stratified", n = 200)
values <- data.frame(value = rnorm(dim(coordinates(value_points))[1], 0 ,1))
value_df <- SpatialPointsDataFrame(value_points, values)
#generate a grid that can be estimated from the fixed points
grd = spsample(gadm_t, type = "regular", n = 4000)
kr <- autoKrige(value~1, value_df, grd)
dat = as.data.frame(kr$krige_output)
#draw the generated grid with the underlying map
ggplot(gadm_t,aes(long,lat)) + geom_polygon(aes(group=group), fill="white") + geom_path(color="white",aes(group=group)) + coord_equal() +
geom_tile(aes(x = x1, y = x2, fill = var1.pred), data = dat) + scale_fill_continuous(low = "white", high = muted("orange"), name = "value")
答案 0 :(得分:15)
我认为你想要的是这些方面的东西。我预测这个自制软件对于大型数据集来说效率非常低,但它适用于一个小的示例数据集。我会查看内核密度,也许是raster
包。但也许这适合你......
以下代码片段计算覆盖原始点数据集的点网格的镉浓度平均值。只考虑接近1000米的点。
library(sp)
library(ggplot2)
loadMeuse()
# Generate a grid to sample on
bb = bbox(meuse)
grd = spsample(meuse, type = "regular", n = 4000)
# Come up with mean cadmium value
# of all points < 1000m.
mn_value = sapply(1:length(grd), function(pt) {
d = spDistsN1(meuse, grd[pt,])
return(mean(meuse[d < 1000,]$cadmium))
})
# Make a new object
dat = data.frame(coordinates(grd), mn_value)
ggplot(aes(x = x1, y = x2, fill = mn_value), data = dat) +
geom_tile() +
scale_fill_continuous(low = "white", high = muted("blue")) +
coord_equal()
导致以下图像:
另一种方法是使用插值算法。克里金就是一个例子。这很容易使用automap包(发现自我推销:),我写了包):
library(automap)
kr = autoKrige(cadmium~1, meuse, meuse.grid)
dat = as.data.frame(kr$krige_output)
ggplot(aes(x = x, y = y, fill = var1.pred), data = dat) +
geom_tile() +
scale_fill_continuous(low = "white", high = muted("blue")) +
coord_equal()
导致以下图像:
然而,如果不知道你的目标是什么,我很难看到你想要的东西。
答案 1 :(得分:2)