填充地理空间多边形图案 - R

7
我有一张波斯尼亚地图,各个市镇被染上了生活在那里的族群的主导颜色。然而,由于要打印成黑白图,我想使用不同的图案代替颜色(或灰度)。
我已经搜索过了,但找不到解决方法。有人有办法吗? shapefile链接 这是我的代码:
library(RColorBrewer)
library(maptools)
library(rgdal)
library(rgeos)
library(ggplot2)
library(gridExtra)

setwd("path")

bosnia <- readOGR("path/to/file", "bosnia_analysis", 
                verbose = TRUE, stringsAsFactors = FALSE)

bosnia <- readShapePoly("path/to/bosnia_analysis.shp",proj4string=CRS("+proj=longlat +datum=WGS84"))
bosnia.df <- bosnia@data

serbs <- bosnia[bosnia$SEPRIORITY > bosnia$CRPRIORITY & bosnia$SEPRIORITY > bosnia$MOPRIORITY,]
croats <-  bosnia[bosnia$CRPRIORITY > bosnia$SEPRIORITY & bosnia$CRPRIORITY > bosnia$MOPRIORITY,]
moslems <- bosnia[bosnia$MOPRIORITY > bosnia$CRPRIORITY & bosnia$MOPRIORITY > bosnia$SEPRIORITY,]

p <- ggplot(bosnia, aes(x = long, y = lat, group = group)) + 
  geom_polygon(aes(x=long,y=lat,group=group), fill="white", colour="grey") +
  geom_polygon(data=serbs, aes(x=long,y=lat,group=group), fill="black", colour="grey") +
  geom_polygon(data=croats, aes(x=long,y=lat,group=group), fill="green", colour="grey") +
  geom_polygon(data=moslems, aes(x=long,y=lat,group=group), fill="red", colour="grey") +
  # Styling
  coord_map() +
  labs(x="Bosnia", y=" ") + 
  theme_bw() + 
  theme(panel.grid.minor=element_blank(), panel.grid.major=element_blank()) + 
  theme(axis.ticks = element_blank(), axis.text.x = element_blank(), axis.text.y = element_blank()) + 
  theme(panel.border = element_blank())

p

这给我提供了以下地图: 在这里输入图片描述

https://dev59.com/S2Ei5IYBdhLWcg3wYLaT#21339558 - CMichael
你有没有关于ggplot2和shapefiles的初学者文献? - user1406647
这只是另一种选择:http://gis.stackexchange.com/questions/87486/help-choosing-most-suitable-bivariate-choropleth-mapping-coloring-scheme/193055#193055 - thiagoveloso
2个回答

15

使用基本图形来替代 ggplot。虽然对于只有三组数据,我认为使用黑色、白色和中灰色应该可以正常工作。

放弃 ggplot,改用基础绘图。虽然在只有三个组时,我认为使用黑色、白色和中灰色可能效果不错。

require(sp)
require(rgdal)

bosnia = readOGR(".","bosnia_analysis")
proj4string(bosnia)=CRS("+init=epsg:4326")

不要将数据集分为三个,而是从三个 TRUE/FALSE 变量中创建一个新的分类变量:

改为:将三个 TRUE/FALSE 变量合并成一个新的分类变量,而不是将数据集分成三个部分。

serbs = bosnia$SEPRIORITY > bosnia$CRPRIORITY & bosnia$SEPRIORITY > bosnia$MOPRIORITY
croats =  bosnia$CRPRIORITY > bosnia$SEPRIORITY & bosnia$CRPRIORITY > bosnia$MOPRIORITY
moslems = bosnia$MOPRIORITY > bosnia$CRPRIORITY & bosnia$MOPRIORITY > bosnia$SEPRIORITY

bosnia$group=NA
bosnia$group[serbs]="Serb"
bosnia$group[croats]="Croat"
bosnia$group[moslems]="Moslem"
bosnia$group=factor(bosnia$group)

检查没有人属于多个类别:

sum(serbs&&croats&&moslems) # should be zero

现在你可以这样得到一个漂亮的彩色图表:

spplot(bosnia, "group")

但我看不出如何以不同的单色风格完成这个任务,所以只能回归基本图形:

plot(bosnia,density=c(5,10,15)[bosnia$group], angle=c(0,45,90)[bosnia$group])

波斯尼亚阴影地图

根据个人口味调整参数。您可以使用legend使用相同的参数创建漂亮的图例。


有没有使用ggplot中的geom_sf来完成这个操作的方法? - NBE
1
请使用as(x,"Spatial")将您的sf对象转换为sp类,使用library(sp)并使用上述技术进行绘图。如果您想这样做,请向ggplot2提交功能请求。 - Spacedman
抓住了..感谢你的帮助! - NBE

2
有点晚了,但这可能会有所帮助。您可以使用sf创建网格,并操纵它以提取特定点并将其连接以创建新的模式:
library(sf)

bosnia <- st_read("~/R/mapslib/OTROS/Bosnia")
st_crs(bosnia) <- 4326
serbs <-
  bosnia[bosnia$SEPRIORITY > bosnia$CRPRIORITY &
           bosnia$SEPRIORITY > bosnia$MOPRIORITY, ]
croats <-
  bosnia[bosnia$CRPRIORITY > bosnia$SEPRIORITY &
           bosnia$CRPRIORITY > bosnia$MOPRIORITY, ]
moslems <-
  bosnia[bosnia$MOPRIORITY > bosnia$CRPRIORITY &
           bosnia$MOPRIORITY > bosnia$SEPRIORITY, ]

ex = list(
  horizontal = c(1, 2),
  vertical = c(1, 4),
  left2right = c(2, 4),
  right2left = c(1, 3)
)
pattern <- function(x, size, pattern) {
  ex = list(
    horizontal = c(1, 2),
    vertical = c(1, 4),
    left2right = c(2, 4),
    right2left = c(1, 3)
  )
  fillgrid = st_make_grid(x, cellsize = size)
  endsf = lapply(1:length(fillgrid), function(j)
    sf::st_linestring(sf::st_coordinates(fillgrid[j])[ex[[pattern]], 1:2]))
  endsf = sf::st_sfc(endsf, crs = sf::st_crs(x))
  endsf = sf::st_intersection(endsf, x)
  endsf = endsf[sf::st_geometry_type(endsf)
                %in% c("LINESTRING", "MULTILINESTRING")]
  endsf = sf::st_line_merge(sf::st_union(endsf))
  return(endsf)
}

serbgrid = pattern(serbs, 0.05, "vertical")
moslgrid = pattern(moslems, 0.05, "left2right")
crogrid = pattern(croats, 0.05, "horizontal")


par(mar = c(0, 0, 0, 0))
plot(st_geometry(bosnia))
plot(serbgrid, add = T)
plot(moslgrid, add = T)
plot(crogrid, add = T)

波斯尼亚的填充图案R地图

请注意,这是我开发的一个简化版本的函数,您可以在这里看到完整代码,并在此文章中查看完整演示。


1
我编辑了帖子,并提供了一个简化版本的函数,希望现在能够有所帮助。 - dieghernan
你可以请求 sf 的开发人员将你的模式函数加入到软件包中吗?它非常有用! - nya
1
实际上,我正在为其包含在“制图”中而工作,请参见https://github.com/riatelab/cartography/issues/57。可以从https://github.com/dieghernan/cartography安装一个可用的软件包。 - dieghernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接