R地图-陆地边界的代表性较差

时间:2019-03-22 12:35:37

标签: r ggplot2 maptools

我绘制了南半球的南部。我的问题是边界划分不佳的澳大利亚。

我的数据:

library("maptools")
library("ggplot2")
library("tidyverse")

ylim_map <- c(-90, -30)
xlim_map <- c(-180, 180)
world <- maps::map("world", fill=TRUE, plot=FALSE, ylim = ylim_map)

以正确的格式为ggplot转换数据:

IDs <- sapply(strsplit(world$names, ":"), function(x) x[1])
world <- map2SpatialPolygons(world, IDs = IDs, 
                             proj4string = CRS("+proj=longlat +datum=WGS84"))
world_map <- fortify(world)
world_map <- world_map[which(between(world_map$lat, ylim_map[1], ylim_map[2]) &
                               between(world_map$lon, xlim_map[1], xlim_map[2])),]

还有我的情节:

ggplot() +

  coord_map("orthographic", orientation = c(-90, 0, 0), 
            xlim = xlim_map, ylim = c(ylim_map[1], ylim_map[2] + 10)) +

  geom_map(data = world_map, map = world_map,
           aes(x = long, y = lat, map_id = id), fill = "black") +

  geom_text(aes(x = 180, y = ylim_map[2]+5, label = "180°E"), color = "black") +
  geom_text(aes(x = 90, y = ylim_map[2]+5, label = "90°E"), angle = -90, color = "black") +
  geom_text(aes(x = 0, y = ylim_map[2]+5, label = "0°"), color = "black") +
  geom_text(aes(x = -90, y = ylim_map[2]+5, label = "90°W"), angle = 90, color = "black") +

  labs(y = "", x = "") +

  # Theme
  theme(text = element_text(size = 20),
        panel.background = element_blank(),
        axis.title = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        axis.line = element_blank(),
        aspect.ratio = 1) 

enter image description here

1 个答案:

答案 0 :(得分:1)

TLDR

您需要关闭多边形。

说明

让我们删除无关的代码并放大到澳大利亚。 (尽管实际上非洲和南美也存在该问题;但那里并没​​有那么明显...)

我们可以看到第一行的行为不正确。它与更南端的海岸线相交,而不是坚持其正确的纬度水平:

ggplot() +
  coord_map("orthographic", orientation = c(-40, 130, 0)) +
  geom_map(data = world_map, map = world_map,
           aes(x = long, y = lat, map_id=id), 
           fill = "darkgrey") +
  theme_bw()

illustration 1

现在geom_map层实际上是在绘制多边形,并且?geom_polygon状态为:

  

多边形与路径(由geom_path()绘制)非常相似,除了   起点和终点已连接且内部已着色   由fill。团队审美决定了哪些案例是相关的   一起变成一个多边形。

如果我们用等价的geom_map / geom_polygon替换geom_path层,情况将变得更加明显:与澳大利亚相对应的多边形没有顶线。而是,路径从一个角开始,在对角结束。 geom_polygon用一条直线连接,当坐标系不是线性的(而coord_map不是)时,它们可能与其他直线相交:

ggplot() +
  coord_map("orthographic", 
            orientation = c(-40, 130, 0)) +
  geom_polygon(data = world_map,
               aes(x = long, y = lat, group = group), 
               fill = "lightgrey") +
  geom_path(data = world_map,
            aes(x = long, y = lat, group = group)) +
  theme_bw()

illustration 2

解决方案

我们可以通过在末端重复第一个点来手动关闭每个多边形。 (对于已经关闭的多边形,这没有其他影响。)

library(dplyr)

world_map2 <- world_map %>%
  group_by(group) %>%              # each group corresponds to a unique polygon
  arrange(order) %>%               # sort points in the appropriate sequence
  slice(c(1:n(), 1)) %>%           # repeat first row after last row
  mutate(order = seq(1, n())) %>%  # define new order for n+1 rows
  ungroup()

检查多边形是否已关闭,并且澳大利亚的第一行现在可以很好地跟踪其纬度级别:

ggplot() +
  coord_map("orthographic", 
            orientation = c(-40, 130, 0)) +
  geom_polygon(data = world_map2,
               aes(x = long, y = lat, group = group), 
               fill = "lightgrey") +
  geom_path(data = world_map2,
            aes(x = long, y = lat, group = group)) +
  theme_bw()

illustration 3

将其应用于原始用例:

ggplot() +

  coord_map("orthographic", orientation = c(-90, 0, 0), 
            xlim = xlim_map, ylim = c(ylim_map[1], ylim_map[2] + 10)) +

  geom_map(data = world_map2, map = world_map2,
           aes(x = long, y = lat, map_id = id), fill = "black") +

  geom_text(aes(x = 180, y = ylim_map[2]+5, label = "180°E"), color = "black") +
  geom_text(aes(x = 90, y = ylim_map[2]+5, label = "90°E"), angle = -90, color = "black") +
  geom_text(aes(x = 0, y = ylim_map[2]+5, label = "0°"), color = "black") +
  geom_text(aes(x = -90, y = ylim_map[2]+5, label = "90°W"), angle = 90, color = "black") +

  labs(y = "", x = "") +

  # Theme
  theme(text = element_text(size = 20),
        panel.background = element_blank(),
        axis.title = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        axis.line = element_blank(),
        aspect.ratio = 1) 

result