ggplot2-如何用颜色填充嵌套的多边形?

时间:2018-06-28 08:28:06

标签: r ggplot2 nested fill polygons

我在一个唯一的SpatialPolygonsDataFrame中有100多个嵌套多边形。我想用ggplot2绘制它们,并且所有这些都必须在地图上可见,即,必须在背景中覆盖较大的多边形。

我发现可以通过在alpha = 0函数中使用geom_polygon来实现此目的,但是如何为每个多边形分配填充颜色?

这是我的代码示例,其中只有2个多边形:

library(ggplot2)

读取合并有两个shapefile的csv文件,然后使用fortify中的maptools将其转换为data.frame。

#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,但是它不起作用。

谢谢


更新

很抱歉,但我意识到我的示例数据不包含嵌套的多边形。

因此,根据https://gis.stackexchange.com/questions/280671/r-create-multipolygon-from-overlapping-polygons-using-sf-package从以下data.frame开始:

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 :(得分:3)

如果您使用sf进行此操作,则可以使用st_area来获取每个多边形的面积(该区域对于未投影的玩具数据没有多大意义,但对于实际形状),然后根据面积对多边形进行排序。这样,ggplot将按ID顺序创建多边形。 要使用geom_sf,您需要github dev version of ggplot2 ,尽管它已被添加到下一个CRAN版本slated for next month (July 2018)中。

首先根据数据创建一个简单的要素集合。在这种情况下,我必须使用summarise(do_union = F)以正确的顺序(per this recent question)将每个点系列变成多边形,然后计算每个点的面积。

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在下面指出的那样,这最初是在顶部放置较大的形状。使用-areadesc(area)降序排列。

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

reprex package(v0.2.0)于2018-06-30创建。

答案 1 :(得分:1)

如果添加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)

或者这是一个以 group 作为填充变量(作为因子)并允许您定义自己的颜色的模型。

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)")

答案 2 :(得分:0)

在ggplot2中可以使用“ fill = aux”的每个形状中添加一个名为“ aux”的变量

您可以尝试做:

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)