R ggplot2与shapefile和csv数据合并以填充多边形
我们每天制作地图,显示我们地区30个不同区域的计算温度水平,每个区域根据不同的水平用不同的颜色填充。这张地图看起来像 现在我想将地图生成切换到R。我已经下载了省级和市级边界(您可以在这里找到或找到),并按照哈德利的方法使用ggplot2绘制了它们 我还可以生成一个包含两列的ascii文件:标识符(CODINE)和每日级别。你可以下载 这是我第一个尝试用R和ggplot2绘制形状文件的脚本,所以可能会有错误,当然可以改进,欢迎您的建议。以下代码(基于Hadley之前提到的代码)对我很有用:R ggplot2与shapefile和csv数据合并以填充多边形,r,merge,ggplot2,R,Merge,Ggplot2,我们每天制作地图,显示我们地区30个不同区域的计算温度水平,每个区域根据不同的水平用不同的颜色填充。这张地图看起来像 现在我想将地图生成切换到R。我已经下载了省级和市级边界(您可以在这里找到或找到),并按照哈德利的方法使用ggplot2绘制了它们 我还可以生成一个包含两列的ascii文件:标识符(CODINE)和每日级别。你可以下载 这是我第一个尝试用R和ggplot2绘制形状文件的脚本,所以可能会有错误,当然可以改进,欢迎您的建议。以下代码(基于Hadley之前提到的代码)对我很有用: &g
> require("rgdal")
> require("maptools")
> require("ggplot2")
> require("plyr")
# Reading municipal boundaries
esp = readOGR(dsn=".", layer="lineas_limite_municipales_etrs89")
muni=subset(esp, esp$PROV1 == "46" | esp$PROV1 == "12" | esp$PROV1 == "3")
muni@data$id = rownames(muni@data)
muni.points = fortify(muni, region="id")
muni.df = join(muni.points, muni@data, by="id")
# Reading province boundaries
prov = readOGR(dsn=".", layer="poligonos_provincia_etrs89")
pr=subset(prov, prov$CODINE == "46" | prov$CODINE == "12" | prov$CODINE == "03" )
pr@data$id = rownames(pr@data)
pr.points = fortify(pr, region="id")
pr.df = join(pr.points, pr@data, by="id")
ggplot(muni.df) + aes(long,lat,group=group) + geom_path(color="blue") +
+ coord_equal()+ geom_path(data=pr.df, +
aes(x=long, y=lat, group=group),color="red", size=0.5)
这段代码绘制了一张包含所有边界的漂亮地图
对于按级别填充多边形,我尝试读取,然后按照中的建议合并
level=read.csv(“levels.dat”,header=T,sep=”“)munlevel=合并(muni.df,level,by=“CODINE”) 但它给出了一个错误 错误en fix.by(by.x,x):“by”必须指定唯一有效的列
我不熟悉shapefile,也许我需要学习更多关于shp数据属性的知识,以找到合并这两个数据集的正确选择。如何合并数据,以便绘制线(市政边界),然后用标高填充 [NB:这个问题是一个多月前提出来的,所以OP可能找到了一种不同的方法来解决他们的问题。我在工作中偶然发现了这个问题。这个答案是为了希望它能让其他人受益。] 这似乎是OP想要的 。。。并使用以下代码生成:
require("rgdal")
require("maptools")
require("ggplot2")
require("plyr")
# read temperature data
setwd("<location if your data file>")
temp.data <- read.csv(file = "levels.dat", header=TRUE, sep=" ", na.string="NA", dec=".", strip.white=TRUE)
temp.data$CODINE <- str_pad(temp.data$CODINE, width = 5, side = 'left', pad = '0')
# read municipality polygons
setwd("<location of your shapefile")
esp <- readOGR(dsn=".", layer="poligonos_municipio_etrs89")
muni <- subset(esp, esp$PROVINCIA == "46" | esp$PROVINCIA == "12" | esp$PROVINCIA == "3")
# fortify and merge: muni.df is used in ggplot
muni@data$id <- rownames(muni@data)
muni.df <- fortify(muni)
muni.df <- join(muni.df, muni@data, by="id")
muni.df <- merge(muni.df, temp.data, by.x="CODIGOINE", by.y="CODINE", all.x=T, a..ly=F)
# create the map layers
ggp <- ggplot(data=muni.df, aes(x=long, y=lat, group=group))
ggp <- ggp + geom_polygon(aes(fill=LEVEL)) # draw polygons
ggp <- ggp + geom_path(color="grey", linestyle=2) # draw boundaries
ggp <- ggp + coord_equal()
ggp <- ggp + scale_fill_gradient(low = "#ffffcc", high = "#ff4444",
space = "Lab", na.value = "grey50",
guide = "colourbar")
ggp <- ggp + labs(title="Temperature Levels: Comunitat Valenciana")
# render the map
print(ggp)
连接必须在公共字段上完成,这就是大多数问题的根源。原始形状文件中的每个多边形都具有唯一的ID属性。在shapefile上运行fortify(…)
将创建一列id
,该列基于此。但是数据部分中没有ID列。相反,多边形ID存储为行名称。因此,首先我们必须在muni@data
如下所示:
muni@data$id <- rownames(muni@data)
要创建贴图,我们需要根据温度级别设置填充颜色。为此,我们需要将LEVEL
列从temp.data
连接到muni.df
。在temp.data
中有一个字段CODINE
,用于标识市政当局。现在,在muni.df
中还有一个相应的字段CODIGOINE
。但是有一个问题:CODIGOINE
是char(5)
,带有前导零,而CODINE
是整数,这意味着前导零丢失(可能是从Excel导入的?)。因此,仅仅在这两个字段上进行连接不会产生匹配。我们必须首先将CODINE
转换为带前导零的char(5)
:
temp.data$CODINE <- str_pad(temp.data$CODINE, width = 5, side = 'left', pad = '0')
我们使用merge(…)
而不是join(…)
,因为join字段具有不同的名称,join(…)
要求它们具有相同的名称。(注意,join(…)
更快,如果可能的话应该使用)。因此,最后,我们有一个数据框,其中包含用于绘制多边形的所有信息和温度级别
,可用于确定每个多边形的填充颜色
关于OP原始代码的一些注释:
geom_polygon(…)
将绘制(并填充)多边形,geom_path(…)
将绘制边界嗨,我没找到解决办法,但我要试试你的密码。你的地图看起来令人印象深刻,正是我想要的。我不得不暂时离开这个问题,因为我以前还有其他问题要解决。非常感谢你的辛勤工作。如果这对你有帮助,请考虑选择答案(绿色复选标记)。我的SabFEFLE,你的脚本出现了一些问题。我又下载了一次,现在代码运行非常适合我的需要。干得好@jlhoward这太棒了。谢谢你的解释!我不得不做得有点不同。使用
fortify(muni,region='id')
(否则它不使用id
变量)和merge
(我想是另一个版本的dplyr
)。查看此问题的更新以及地图上的一些额外功能,请访问[
muni.df <- join(muni.df, muni@data, by="id")
temp.data$CODINE <- str_pad(temp.data$CODINE, width = 5, side = 'left', pad = '0')
muni.df <- merge(muni.df, temp.data, by.x="CODIGOINE", by.y="CODINE", all.x=T, a..ly=F)