2017-04-04 82 views
4

當繪製世界地圖時,存在ggplot2的問題:它使用相同顏色對整個背景着色,包括情節的實際上並不是全球範圍內,請參閱下面的代碼下面產生的快照(它使用bleading邊緣sf ABD ggplot2版本,但問題是通用的,見下文提到的博客文章):用於ggplot2(和sf)中的世界地圖的整個地球多邊形

#install.packages("devtools") 
    #devtools::install_github("tidyverse/ggplot2") 
    #devtools::install_github("edzer/sfr") 

    library(ggplot2) 
    library(sf) 
    library(rnaturalearth) 
    library(dplyr) 

    theme_map <- function(...) { 
     theme_minimal() + 
     theme(
     text = element_text(family = "Ubuntu Regular", color = "#22211d"), 
     axis.line = element_blank(), 
     axis.text.x = element_blank(), 
     axis.text.y = element_blank(), 
     axis.ticks = element_blank(), 
     axis.title.x = element_blank(), 
     axis.title.y = element_blank(), 
     panel.grid.minor = element_line(color = "#ebebe5", size = 0.2), 
     panel.grid.major = element_line(color = "#ebebe5", size = 0.2), 
     plot.background = element_rect(fill = "#f5f5f2", color = NA), 
     panel.background = element_rect(fill = "#f5f5f2", color = NA), 
     legend.background = element_rect(fill = "#f5f5f2", color = NA), 
     panel.border = element_blank(), 
     ... 
    ) 
    } 

    crs <- "+proj=laea +lat_0=52 +lon_0=10 +x_0=00 +y_0=3210000 +datum=WGS84 +units=m +no_defs" 
    ctrys50m <- ne_countries(scale = 50, type = "countries", returnclass = "sf") %>% 
     select(iso_a3, iso_n3, admin) 

    ggplot() + 
     geom_sf(data = ctrys50m, alpha = 0.15, fill="grey") + 
     coord_map() + 
     coord_sf(crs = crs) + 
     theme_map() 

enter image description here

爲了能夠很好地繪製地球輪廓,在D3.js特殊GeoJSON的type{type: "Sphere"}已添加,看到this thread可以在動作here可以看出:它是外部地球整體黑色邊框下面的快照:

enter image description here

唯一我發現在R/ggplot2是由Matt Strimas-Mackey在他的博客文章Mapping the Longest Commericial Flights in R中發佈的,參見Bounding box and graticules部分和make_bboxproject_recenter函數。

這是相當多的代碼,我想知道一些 sfgeom_sf代碼是否會做出一個更清潔/更簡單的代碼,所以我嘗試:

# whole world WSG84 bounding box 
    sphere <- ne_download(category = "physical", type = "wgs84_bounding_box", returnclass = "sf") 
    sphere_laea <- st_transform(sphere, crs) 
    ggplot() + 
     geom_sf(data = sphere, fill = "#D8F4FF") + 
     coord_sf(crs = crs) + 
     geom_sf(data = ctrys50m, alpha = 0.15, fill="grey") + 
     coord_map() + 
     coord_sf(crs = crs) + 
     theme_map() 

我所得到的只是一個額外的「反子午線「(注意從北極線...)和沒有海洋填充#D8F4FF ... 而多邊形是非常不規則的底部(D3.js大師做了一些智能adaptive resampling增加了準確性的投影線......)

enter image description here

不好的事,我試圖得到GGPLOT2世界地圖整個世界多邊形任何想法? (感謝遠閱讀本!)

回答

6

繼戴夫的建議下,我創建了一個新的刻度足夠小,凸包操作將導致地球的邊境的一個足夠好的近似。 下面的代碼提供了很好的效果(參見後的圖像):

library(ggplot2) 
library(sf) 
library(rnaturalearth) 
library(dplyr) 

crs <- "+proj=laea +lat_0=52 +lon_0=10 +x_0=00 +y_0=3210000 +datum=WGS84 +units=m +no_defs" 

ctrys50m <- ne_countries(scale = 50, type = "countries", returnclass = "sf") %>% 
    select(iso_a3, iso_n3, admin) 

sphere <- st_graticule(ndiscr = 10000, margin = 10e-6) %>% 
    st_transform(crs = crs) %>% 
    st_convex_hull() %>% 
    summarise(geometry = st_union(geometry)) 

ggplot() + 
    geom_sf(data = sphere, fill = "#D8F4FF", alpha = 0.7) + 
    geom_sf(data = ctrys50m, fill="grey") + 
    theme_bw() 

enter image description here

3

我也仍然在發現的sf神奇的過程,所以有可能是更直接的解決你的問題。不過,你可能會發現這種方法非常有用:

爲了提取地球球體的多邊形,只需使用所需的投影的刻度,創建一個凸包,凝聚產生的多邊形。

library(ggplot2) 
library(sf) 
library(rnaturalearth) 
library(dplyr) 

crs <- "+proj=laea +lat_0=52 +lon_0=10 +x_0=00 +y_0=3210000 
     +datum=WGS84 +units=m +no_defs" 

ctrys50m <- ne_countries(scale = 50, type = "countries", returnclass = "sf") %>% 
    select(iso_a3, iso_n3, admin) 

sphere <- st_graticule(st_transform(ctrys50m, crs = crs)) %>% 
    st_convex_hull() %>% 
    summarise(geometry = st_union(geometry)) 

ggplot() + 
    geom_sf(data = sphere, fill = "#D8F4FF", alpha = 0.7) + 
    geom_sf(data = ctrys50m, fill="grey") + 
    #coord_sf(crs = crs) + # not necessary because the crs from the first layer is being used. 
    theme_bw() 

這給你下面的情節,它仍然有一些可見的角落,但可能是足夠的,這取決於你的目的。

enter image description here

+0

這是一個夢幻般的建議。我將使用'ne_countries(scale = 10,...)'有一個更好的多邊形,否則它是一個可行的解決方案。謝謝! – espinielli

+0

我得到了非常好的結果,即沒有可見的角落,下面定義了'sphere':'sphere < - st_graticule(ndiscr = 10000,margin = 10e-6)%>%st_transform(crs = crs)%>%st_convex_hull ()%>%彙總(幾何= st_union(幾何))' – espinielli