ggplot 地图 - 使用 coord_map 时不需要的水平线

ggplot maps - unwanted horizontal lines when using coord_map

当我在 ggplot 包中使用 coord_map 时,无法正确投影欧洲地图。下面的代码在随机位置给我一条奇怪且不需要的水平线。有谁知道如何克服这个问题?

我不想使用 coord_quickmapcoord_cartesian,因为我想保留国家/地区的直线。

library(ggplot2)

map.world <- map_data("world")

ggplot(map.world, aes(x = long, y = lat)) + 
  geom_polygon(mapping = aes(x = long, y = lat, group = group), fill =  "#B3B1B5", color = "#D9D8DA",size = 0.4) +
  theme_minimal() +
  theme(axis.text = element_blank(), text = element_blank(), panel.grid = element_blank()) +
  coord_map(xlim = c(-27,36), ylim = c(34,67))

有两种方法可以解决您的问题:

直接的方法

这种方式只需要稍微调整一下你的代码(注意我使用 magrittr 的转发 pipes):

library(maps)
library(magrittr)
library(maptools)
library(broom)
library(ggplot2)

europe <-  maps::map("world", fill=TRUE, plot=FALSE) %>%
                 maptools::pruneMap(xlim = c(-27,36), ylim = c(34,67))

ggplot(data= broom::tidy(europe)) + 
  geom_polygon(mapping = aes(x = long, y = lat, group = group), 
               fill =  "#B3B1B5", color = "#D9D8DA",size = 0.4) +
  theme_void() +
  coord_map()

"owin/extent" 方法

另一种解决问题的方法是使用 owin 对象。这种对象将允许您创建一个空间 window。那么你只能在世界地图上表示这样的 window 的交集。

使用这种方法,您的代码将如下所示(也使用 magrittr 的转发 pipes 并设置通用 CRS

library(maps)
library(magrittr)
library(spatstat)
library(maptools)
library(raster)
library(broom)
library(ggplot2)

#Defining a general EPSG so there won't be any superposition problems
epsg <- "+proj=longlat +datum=WGS84 +no_defs"

#Using the original maps package, then converting map into SpatialPolygons object
map.world <- maps::map("world", fill=TRUE) %$% 
  maptools::map2SpatialPolygons(., IDs=names,proj4string=CRS(epsg))

#In order to keep the names of the countries we create the following data.frame
country.labs <- sapply(slot(map.world, "polygons"), function(x) slot(x, "ID")) %>% 
  data.frame( ID=1:length(map.world), name=., row.names = .) 

#We convert object map.world into a SpatialPolygonsDataFrame object
map.world.SPDF <- sp::SpatialPolygonsDataFrame(map.world, country.labs) 

#Creating owin object using your zooming coordinates
#This step always requires to load packages 'spatstat' and 'maptools'
zoom <- as(spatstat::as.owin(c(-27,36,34,67)), "SpatialPolygons") 
raster::projection(zoom)=epsg

#Storing intersection between 'zoom' and 'world.map'
europe <- raster::intersect(map.world.SPDF, zoom)

#*country names of object europe can be accessed via europe@data

#Representing object 'europe' using broom::tidy to create a data.frame object
ggplot() + 
  geom_polygon(data = broom::tidy(europe, region="name"), 
               mapping = aes(x = long, y = lat, group = group), 
               fill =  "#B3B1B5", color = "#D9D8DA",size = 0.4) +
  theme_void() +
  coord_map()

#*country names after tidying 'europe' this way are in a new column called 'id'

根据您的工作,您可能需要使用

zoom <- as(raster::extent(c(-27,36,34,67)), "SpatialPolygons")

创建 extent 对象而不是 owin 对象(这里的结果是一样的)

下面显示任何方法得到的结果

如果您需要进行不同的缩放,您可以轻松地将任何备选方案包装在一个函数中。

希望对你有帮助

BONUS BALL:查看 tmap

您可能会感兴趣