карта с ggplot2 - создайте маску, заполняющую поле, исключая одну страну

Возможно ли иметь слой в ggplot, который действует как маска для слоя ggmap? Здесь они добавили полигон страны сверху ggmap.

введите здесь описание изображения

Что я ищу, так это то, что страна будет «дырой» в слое (с альфой), покрывающем все, кроме страны. В некотором смысле обратный пример выше. Код из этого ответа (с добавленной и обновленной прозрачностью для использования geom_cartogram).

library(mapdata)
library(ggmap)
library(ggplot2)
library(ggalt)

# Get Peru map
Peru <- get_map(location = "Peru", zoom = 5, maptype="satellite") 

# This is the layer I wish to put over the top
coast_map <- fortify(map("worldHires", fill = TRUE, plot = FALSE)) 

# Subset data for Peru
peru.coast <- subset(coast_map, region == "Peru")

# Draw a graphic
ggmap(Peru) +
  geom_cartogram(data = peru.coast, map = peru.coast, aes(x = long, y = lat, map_id = region),
           fill="white", color="grey", alpha=.1) +
  xlim(-86, -68) +
  ylim(-20, 0) + 
  labs(x = "Longitude", y = "Latitude") +
  coord_map() +
  theme_classic()

Есть ли способ заполнить все, кроме многоугольника, в ggplot2?


person Lod    schedule 26.05.2017    source источник
comment
Не могли бы вы заменить переменную peru.coast на subset(coast_map, region != "Peru")?   -  person Nancy    schedule 27.05.2017
comment
спасибо за предложение, но нет, вы бы взяли все данные в worldHires, но это не охватывает океаны. Обходной путь может состоять в том, чтобы выбрать всех соседей и шейп-файл океана, но это может легко стать сложным. Я действительно ищу дополнительный или обратный подход.   -  person Lod    schedule 27.05.2017
comment
Я не понимаю, как здесь должен выглядеть результат - вы хотите дырку посередине (т.е. Перу вырезать)?   -  person lukeA    schedule 27.05.2017
comment
Не совсем так, пример выше показывает Перу с прозрачным слоем и окружение как есть. То, что я ищу, это окружение с прозрачным слоем заливки и Перу с альфой = 1.   -  person Lod    schedule 27.05.2017


Ответы (1)


Есть ли способ заполнить все, кроме многоугольника, в ggplot2?

Этот метод может быть немного неортодоксальным, но тем не менее:

library(mapdata)
library(ggmap)
library(ggplot2)
library(raster)
ggmap_rast <- function(map){
  map_bbox <- attr(map, 'bb') 
  .extent <- extent(as.numeric(map_bbox[c(2,4,1,3)]))
  my_map <- raster(.extent, nrow= nrow(map), ncol = ncol(map))
  rgb_cols <- setNames(as.data.frame(t(col2rgb(map))), c('red','green','blue'))
  red <- my_map
  values(red) <- rgb_cols[['red']]
  green <- my_map
  values(green) <- rgb_cols[['green']]
  blue <- my_map
  values(blue) <- rgb_cols[['blue']]
  stack(red,green,blue)
}
Peru <- get_map(location = "Peru", zoom = 5, maptype="satellite") 
data(wrld_simpl, package = "maptools")
polygonMask <- subset(wrld_simpl, NAME=="Peru")
peru <- ggmap_rast(Peru)
peru_masked <- mask(peru, polygonMask, inverse=T)
peru_masked_df <- data.frame(rasterToPoints(peru_masked))
ggplot(peru_masked_df) + 
  geom_point(aes(x=x, y=y, col=rgb(layer.1/255, layer.2/255, layer.3/255))) + 
  scale_color_identity() + 
  coord_quickmap()

введите здесь описание изображения

Через это, это и это вопросы/ответы.


То, что я ищу, это окружение с прозрачным слоем заливки и Перу с альфой = 1.

Если сначала подумать, это легко. Однако потом увидел и вспомнил, что geom_polygon очень не любит полигоны с дырками. К счастью, geom_polypath из пакета ggpolypath это делает. Однако будет выдана ошибка "Ошибка в grid.Call.graphics(L_path, x$x, x$y, index, switch(x$rule, Winding = 1L..") с ggmaps расширение панели по умолчанию.

Так что вы могли бы сделать

library(mapdata)
library(ggmap)
library(ggplot2)
library(raster)
library(ggpolypath) ## plot polygons with holes
Peru <- get_map(location = "Peru", zoom = 5, maptype="satellite") 
data(wrld_simpl, package = "maptools")
polygonMask <- subset(wrld_simpl, NAME=="Peru")
bb <- unlist(attr(Peru, "bb"))
coords <- cbind(
  bb[c(2,2,4,4)],
  bb[c(1,3,3,1)])
sp <- SpatialPolygons(
  list(Polygons(list(Polygon(coords)), "id")), 
  proj4string = CRS(proj4string(polygonMask)))
sp_diff <- erase(sp, polygonMask)
sp_diff_df <- fortify(sp_diff)  

ggmap(Peru,extent="normal") +
  geom_polypath(
    aes(long,lat,group=group),
    sp_diff_df, 
    fill="white",
    alpha=.7
  )

введите здесь описание изображения

person lukeA    schedule 26.05.2017
comment
большое спасибо, я повнимательнее рассмотрю как код, так и ссылки. Вероятно, мой вопрос был бы более точным, спрашивая, можно ли определить векторную маску как инверсию границ холста за вычетом многоугольника. - person Lod; 27.05.2017
comment
@Lod Может быть, это потому, что я работаю в маркетинге, но я бы спросил что-то вроде того, как заполнить все без многоугольника посередине. Я не понимаю таких вещей, как векторная маска или обратные границы холста. Просто пишите с мыслью о ребенке, а не о профессоре. ;-) - person lukeA; 27.05.2017