ggplot2 - как заполнить вложенные полигоны цветом? - PullRequest
0 голосов
/ 28 июня 2018

У меня> 100 вложенных полигонов в уникальном SpatialPolygonsDataFrame. Я хочу нанести на них ggplot2 и , все они должны быть видны на карте , то есть наложение больших полигонов должно быть на заднем плане.

Я обнаружил, что могу добиться этого, используя alpha = 0 в функции geom_polygon, но как назначить цвет заливки для каждого многоугольника?

Вот пример моего кода с двумя полигонами:

library(ggplot2)

Чтение CSV-файла с двумя шейп-файлами, объединенными, а затем преобразованными в data.frame с fortify из maptools.

#read csv file shape_1_2.csv
shape_1_2 = read.csv('shape_1_2.csv', stringsAsFactors = FALSE)

#plot
ggplot() +
geom_polygon(data = shape_1_2, aes(x = long, y = lat, group = group), 
             colour = 'black', size = 1, linetype = 'solid', alpha = 0)

и относительная карта:

enter image description here

Как я могу залить цветом эти два полигона?

Я пытался добавить fill='black' в aes и geom_polygon, но это не работает.

Спасибо


Обновление

Прошу прощения, но я понял, что в моих данных в качестве примера НЕТ вложенных полигонов.

Итак, начиная со следующих data.frame согласно https://gis.stackexchange.com/questions/280671/r-create-multipolygon-from-overlapping-polygons-using-sf-package:

shape_df = data.frame(
    lon = c(0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 2, 2, 0.8, 1, 1, 2, 2, 1, 1),
    lat = c(0, 0, 1, 1.5, 0, 1, 1, 2, 2, 1, 1, 1, 2, 2, 1, 0, 0, 1, 1, 0),
    var = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3 ,3 ,3 ,3 ,3, 4 ,4 ,4, 4, 4)
)

И мой код для построения (с alpha=0):

ggplot() +
    geom_polygon(data = shape_df, aes(x = lon, y = lat, group = var), 
                 colour = 'black', size = 1, linetype = 'solid', alpha = 0)

С относительной картой:

enter image description here

Как мне заполнить различные области, присутствующие на карте, одним ИЛИ до 4 цветов, чтобы большие полигоны оставались на фоне меньших?

Ответы [ 3 ]

0 голосов
/ 30 июня 2018

Если вы добавите fill, но у вас будет alpha=0, вы не увидите никаких цветов, так как они будут на 100% прозрачными.

Я не уверен, чего именно вы хотите добиться, поскольку я вижу 3 полигона, которые вы можете по-разному раскрасить, а не только 2.

Что если вы попробуете этот вызов ggplot, который принимает id в качестве переменной заполнения (как фактор):

ggplot() +
  geom_polygon(data = shape_1_2, aes(x = long, y = lat, group = group, fill=factor(id)), 
               colour = 'black', size = 1, linetype = 'solid', alpha = 1)

Или этот, который принимает группу в качестве переменной заполнения (как фактор) и позволяет вам определять свои собственные цвета.

ggplot(shape_1_2) +
  aes(x = long, y = lat, group = group, fill=factor(group)) + 
  geom_polygon() +
  scale_fill_manual(values = c("green", "red", "blue")) +
  geom_path(color="black")

enter image description here

Вы также можете использовать функцию scale_fill_brewer, которая позволяет выбрать предопределенную цветовую палитру (показать возможные палитры с помощью: display.brewer.all())

ggplot(shape_1_2) +
  aes(x = long, y = lat, group = group, fill=factor(group)) + 
  geom_polygon() +
  scale_fill_brewer(palette = "RdYlGn") +
  geom_path(color="black") +
  ggtitle("fill=factor(group)")
0 голосов
/ 30 июня 2018

Если вы сделаете это с sf, вы можете использовать st_area, чтобы получить площадь каждого многоугольника (область не имеет большого смысла для непроецированных данных игрушек, но будет иметь смысл с фактическими формами), затем заказывайте полигоны по площади. Таким образом, ggplot будет создавать полигоны по порядку по идентификатору. Чтобы использовать geom_sf, вам нужна версия github dev ggplot2, хотя она будет добавлена ​​к следующему выпуску CRAN, запланирован на следующий месяц (июль 2018 года) .

Сначала создайте простую коллекцию объектов на основе данных. В этом случае мне пришлось использовать summarise(do_union = F), чтобы превратить каждую серию точек в многоугольник в правильном порядке ( для этого недавнего вопроса ), а затем вычислить площадь каждой из них.

library(tidyverse)
library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.1.3, proj.4 4.9.3

shape_df <- data.frame(
  lon = c(0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 2, 2, 0.8, 1, 1, 2, 2, 1, 1),
  lat = c(0, 0, 1, 1.5, 0, 1, 1, 2, 2, 1, 1, 1, 2, 2, 1, 0, 0, 1, 1, 0),
  var = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3 ,3 ,3 ,3 ,3, 4 ,4 ,4, 4, 4)
)

shape_areas <- shape_df %>%
  st_as_sf(coords = c("lon", "lat")) %>%
  group_by(var) %>%
  summarise(do_union = F) %>%
  st_cast("POLYGON") %>%
  st_cast("MULTIPOLYGON") %>%
  mutate(area = st_area(geometry)) %>% 
  mutate(var = as.factor(var)) 

shape_areas
#> Simple feature collection with 4 features and 3 fields
#> geometry type:  MULTIPOLYGON
#> dimension:      XY
#> bbox:           xmin: 0 ymin: 0 xmax: 2 ymax: 2
#> epsg (SRID):    NA
#> proj4string:    NA
#>   var do_union area                       geometry
#> 1   1    FALSE 1.25 MULTIPOLYGON (((0 0, 1 0, 1...
#> 2   2    FALSE 1.00 MULTIPOLYGON (((0 1, 1 1, 1...
#> 3   3    FALSE 1.10 MULTIPOLYGON (((1 1, 2 1, 2...
#> 4   4    FALSE 1.00 MULTIPOLYGON (((1 0, 2 0, 2...

Если я строю график в этой точке, область не имеет отношения к порядку построения; он просто заказывает на var, численно:

shape_areas %>%
  ggplot() +
    geom_sf(aes(fill = var), alpha = 0.9)

Но если я использую forcats::fct_reorder, чтобы переупорядочить var в качестве фактора за счет уменьшения площади, полигоны будут строиться в порядке с самыми большими полигонами внизу и более мелкими полигонами сверху. Редактировать: , как указывало @SeGa ниже, это изначально помещало большие фигуры сверху. Используйте -area или desc(area) для заказа по убыванию.

shape_areas %>%
  mutate(var = var %>% fct_reorder(-area)) %>%
  ggplot() +
  geom_sf(aes(fill = var), alpha = 0.9)

Создано в 2018-06-30 пакетом Представить (v0.2.0).

0 голосов
/ 29 июня 2018

Добавляя переменную с именем «aux» к каждой фигуре, вы можете использовать «fill = aux» в ggplot2

Вы можете попробовать сделать:

library(maptools)
library(ggplot2)

shape_1 <- readShapePoly('poly_1.shp') %>%
fortify()  %>%
mutate(aux = c("1"))

shape_2 <- readShapePoly('poly_2.shp') %>%
fortify()  %>%
mutate(aux = c("2"))

shape_1_2 = rbind(shape_1, shape_2)

ggplot() +
geom_polygon(data = shape_1_2, aes(x = long, y = lat, group = group), 
             colour = 'black', size = 0.1, linetype = 'solid', alpha = 0, fill = aux)
...