Lors du traçage de cartes du monde, il y a un problème avec ggplot2: il colore tout l'arrière-plan avec la même couleur, y compris les coins du tracé qui ne font pas réellement partie du globe, voir l'instantané ci-dessous produit par le code suivant (il utilise des versions bleading edge sf abd ggplot2 mais le problème est générique, voir l'article de blog mentionné ci-dessous):

    #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=4321000 +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

Afin de pouvoir tracer joliment le contour de la Terre, dans D3.js un GeoJSON type spécial, {type: "Sphere"} a été ajouté, voir ce fil qui peut être vu en action ici : il s'agit de la bordure noire extérieure de la Terre entière dans l'instantané suivant:

enter image description here

La seule astuce que j'ai trouvée dans R / ggplot2 est celle publiée par Matt Strimas-Mackey, dans son article de blog Cartographie des vols commerciaux les plus longs de R, voir le Boîte englobante et graticules et les fonctions make_bbox et project_recenter.

Ce sont beaucoup de code et je me demandais si certains Le code sf ou geom_sf donnerait un code plus propre / plus simple, alors j'ai essayé:

    # 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()

Ce que je reçois, c'est juste un "anti-méridien" supplémentaire (notez la ligne du pôle Nord ...) et pas d ' océans remplis de #D8F4FF ... Et le polygone est assez irrégulier en bas (les gourous de D3.js ont fait un rééchantillonnage adaptatif intelligent pour augmenter la précision des lignes projetées ...)

enter image description here

Des idées sur ce qui ne va pas dans ma tentative d'obtenir un polygone du monde entier pour les cartes du monde ggplot2? (Merci d'avoir lu jusqu'ici!)

7
espinielli 4 avril 2017 à 15:57

2 réponses

Meilleure réponse

Suite à la suggestion de Dave, j'ai créé un nouveau réticule suffisamment petit pour que l'opération de coque convexe aboutisse à une approximation suffisamment bonne de la bordure du globe . Le code suivant donne de très bons résultats (voir l'image après):

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

crs <- "+proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +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

8
espinielli 7 avril 2017 à 13:05

Je suis également encore en train de découvrir la magie de sf, il peut donc y avoir des solutions plus simples à votre problème. Néanmoins, vous pourriez trouver cette approche utile:

Afin d'extraire le polygone de la sphère terrestre, utilisez simplement le réticule de la projection souhaitée, créez une coque convexe et unissez les polygones résultants.

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

crs <- "+proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +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()

Cela vous donne le tracé suivant, qui a encore des coins visibles mais peut être suffisant en fonction de votre objectif.

enter image description here

3
Dave 6 avril 2017 à 09:20