尝试在具有属性的 tmap shapefile 中绘制
Trying to plot in tmap shapefile with attribute
我正在尝试处理挪威的市政数据,我对 QGIS、shapefile 和在 R 中绘制它是全新的。我从这里下载市政当局:
Administrative enheter kommuner / Administrative units municipalities
可复制的文件在这里:
Joanna's github
我已经下载了QGIS,所以我可以在那里打开GEOJson文件并将其转换为shapefile。我能够做到这一点,并将数据读入 R:
library(sf)
test=st_read("C:/municipality_shape.shp")
head(test)
我自己给不同的城市不同 values/ranks,我称之为 faktor,我已经将这个分类存储在我称之为 [=42] 的数据框中=]df_new。我希望将此 "classification" 合并到我上面的 "test" 对象上,并希望将具有分类属性的地图绘制到地图上:
test33=merge(test, df_new[,c("Kommunekode_str","faktor")],
by=c("Kommunekode_str"), all.x=TRUE)
这行得通,但是当我用 tmap
、
绘制它时
library(tmap)
tmap_mode("view")
tm_shape(test33) +
tm_fill(col="faktor", alpha=0.6, n=20, palette=c("wheat3","red3")) +
tm_borders(col="#000000", lwd=0.2)
它抛出这个错误:
Error in object[-omit, , drop = FALSE] : incorrect number of
dimensions
如果我只用底图,
plot(test33)
我明白了:
你看我得到了三个地块。这和我上面的错误有关系吗?
我认为这里的主要问题是您尝试绘制的形状太复杂,因此 tmap
很难加载所有这些数据。 ggplot
也无法加载多边形。
如果您正在制作等值线图,您可能不需要多边形的精确度那么高,所以我建议首先简化 您的多边形。根据我的经验,最好的方法是使用包 rmapshaper
:
# keep = 0.02 will keep just 2% of the points in your polygons.
test_33_simple <- rmapshaper::ms_simplify(test33, keep = 0.02)
我现在可以使用您的代码生成以下内容:
tmap_mode("view")
tm_shape(test_33_simple) +
tm_fill(col="faktor", alpha=0.6, n=20, palette=c("wheat3","red3")) +
tm_borders(col="#000000", lwd=0.2)
这会生成一个 交互式 地图,并且配色方案不能很好地区分城市之间的差异。
静态版本
既然你在评论中说你不确定你想要交互式地图还是静态地图,我将给出一个静态地图示例和一些示例配色方案。
下面使用 classInt
包为您的地图设置休息点。一种流行的中断方案是 'fisher',它使用 fisher-jenks 算法。确保您研究了各种不同的选项以选择适合您的情况的选项:
library(ggplot2)
library(dplyr)
library(sf)
library(classInt)
breaks <- classIntervals(test_33_simple$faktor, n = 6, style = 'fisher')
#label breaks
lab_vec <- vector(length = length(breaks$brks)-1)
rounded_breaks <- round(breaks$brks,2)
lab_vec[1] <- paste0('[', rounded_breaks[1],' - ', rounded_breaks[2],']')
for(i in 2:(length(breaks$brks) - 1)){
lab_vec[i] <- paste0('(',rounded_breaks[i], ' - ', rounded_breaks[i+1], ']')
}
test_33_simple <- test_33_simple %>%
mutate(faktor_class = factor(cut(faktor, breaks$brks, include.lowest = T), labels = lab_vec))
# map
ggplot(test_33_simple) +
geom_sf(aes(fill = faktor_class), size= 0.2) +
scale_fill_viridis_d() +
theme_minimal()
我正在尝试处理挪威的市政数据,我对 QGIS、shapefile 和在 R 中绘制它是全新的。我从这里下载市政当局: Administrative enheter kommuner / Administrative units municipalities
可复制的文件在这里: Joanna's github
我已经下载了QGIS,所以我可以在那里打开GEOJson文件并将其转换为shapefile。我能够做到这一点,并将数据读入 R:
library(sf)
test=st_read("C:/municipality_shape.shp")
head(test)
我自己给不同的城市不同 values/ranks,我称之为 faktor,我已经将这个分类存储在我称之为 [=42] 的数据框中=]df_new。我希望将此 "classification" 合并到我上面的 "test" 对象上,并希望将具有分类属性的地图绘制到地图上:
test33=merge(test, df_new[,c("Kommunekode_str","faktor")],
by=c("Kommunekode_str"), all.x=TRUE)
这行得通,但是当我用 tmap
、
library(tmap)
tmap_mode("view")
tm_shape(test33) +
tm_fill(col="faktor", alpha=0.6, n=20, palette=c("wheat3","red3")) +
tm_borders(col="#000000", lwd=0.2)
它抛出这个错误:
Error in object[-omit, , drop = FALSE] : incorrect number of
dimensions
如果我只用底图,
plot(test33)
我明白了:
你看我得到了三个地块。这和我上面的错误有关系吗?
我认为这里的主要问题是您尝试绘制的形状太复杂,因此 tmap
很难加载所有这些数据。 ggplot
也无法加载多边形。
如果您正在制作等值线图,您可能不需要多边形的精确度那么高,所以我建议首先简化 您的多边形。根据我的经验,最好的方法是使用包 rmapshaper
:
# keep = 0.02 will keep just 2% of the points in your polygons.
test_33_simple <- rmapshaper::ms_simplify(test33, keep = 0.02)
我现在可以使用您的代码生成以下内容:
tmap_mode("view")
tm_shape(test_33_simple) +
tm_fill(col="faktor", alpha=0.6, n=20, palette=c("wheat3","red3")) +
tm_borders(col="#000000", lwd=0.2)
这会生成一个 交互式 地图,并且配色方案不能很好地区分城市之间的差异。
静态版本
既然你在评论中说你不确定你想要交互式地图还是静态地图,我将给出一个静态地图示例和一些示例配色方案。
下面使用 classInt
包为您的地图设置休息点。一种流行的中断方案是 'fisher',它使用 fisher-jenks 算法。确保您研究了各种不同的选项以选择适合您的情况的选项:
library(ggplot2)
library(dplyr)
library(sf)
library(classInt)
breaks <- classIntervals(test_33_simple$faktor, n = 6, style = 'fisher')
#label breaks
lab_vec <- vector(length = length(breaks$brks)-1)
rounded_breaks <- round(breaks$brks,2)
lab_vec[1] <- paste0('[', rounded_breaks[1],' - ', rounded_breaks[2],']')
for(i in 2:(length(breaks$brks) - 1)){
lab_vec[i] <- paste0('(',rounded_breaks[i], ' - ', rounded_breaks[i+1], ']')
}
test_33_simple <- test_33_simple %>%
mutate(faktor_class = factor(cut(faktor, breaks$brks, include.lowest = T), labels = lab_vec))
# map
ggplot(test_33_simple) +
geom_sf(aes(fill = faktor_class), size= 0.2) +
scale_fill_viridis_d() +
theme_minimal()