English 中文(简体)
Fill Sub Division of Chloropeth Map with multi Colors
原标题:Fill Subdivisions of Chloropeth Map with multiple Colors
The bounty expires tomorrow. Answers to this question are eligible for a +100 reputation bounty. M-- is looking for a more detailed answer to this question.

我想建立一个德国的一块地块,其16个联邦议院(Subdivisons)中的每一个都根据一系列标准的不同而有不同的肤色。 在底部,你发现代表的草图。 设想是,你认为哪一个分区符合哪些标准。

每一 cr都有不同的颜色,即:

library(RColorBrewer)
Colors <- brewer.pal(5, "Spectral") 
Colors
[1] "#D7191C" "#FDAE61" "#FFFFBF" "#ABDDA4" "#2B83BA"

现在,我有一份16份名单,其中载有每个联邦议院的肤色,取决于他们符合哪些标准。 例如:

Berlin
[1] "#D7191C" "#FDAE61" "#FFFFBF" "#ABDDA4" 
Bavaria
[1] "#D7191C" "#FDAE61"
Hamburg
[1] "#ABDDA4"

如你所看到的那样,它们都是长短不一的。

现在,我很想知道,我如何能够把这些多彩的信息传递给我的氯乙烯地图? 我从

下面是地图的明细图,你在那里只能看到联邦议院的边界(附后)。

library(sf)
library(cartography)
plot(st_geometry(Germany), col = NA, border = "white", bg = "#aadaff")

通过我的彩色清单

"col = Colors"

当然,不是工作,也不是用希望的颜色填充分区。

“Desired

最佳回答

Update:

OP称,他们需要每个联邦议院的多重肤色。 假设他们有一份有名的清单或有色人的数据框架,他们可以加入其形状档案。 在这方面,我正在制造一套任意的颜色。 我将颜色分配给每个国家(向其中一些国家转让多种颜色)。

Then I would divide each state that has multiple colors to equal parts.

最后,我策划了分裂的多角(没有边界),并将把原地块混凝土块地上,只划定一个白色边界(如果我选择黑色显示这些边界),以显示原来的分区/州边界。 我不敢肯定,为什么背景不奏效。

I 认为这里应当有一个更好的办法,因此,应该有一个放弃。

#### libraries ####

library(sf)
library(sp)
library(dismo)
library(deldir)
library(dplyr) 
#### downloading the data ####

download.file("https://geodata.ucdavis.edu/gadm/gadm4.1/shp/gadm41_DEU_shp.zip",
              "gadm41_DEU_shp.zip")
unzip("gadm41_DEU_shp.zip", exdir= "DEU_adm")

Germany <- st_read(dsn="DEU_adm\gadm41_DEU_1.shp", quiet = TRUE)
#### pre-processing the data and defining the split funciton ####

## creating a set of random colors, you should use your desired colors
set.seed(123)
cp <- sample(grDevices::colors()[grep( gr(a|e)y|white ,
             grDevices::colors(), invert = T)], 24)

Germany$COLORS <- I(list(cp[1], cp[2:3], cp[3:5], cp[6:9], 
                         cp[10], cp[11], cp[12], cp[13],
                         cp[14], cp[15], cp[16], cp[17],
                         cp[18], cp[19], cp[20], cp[21:24]))

wgs84 <- "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"

## taken from https://gis.stackexchange.com/a/440698/93948
## split polygons 
split_poly <- function(sf_poly, n_areas) {
  # Create random points
  points_rnd <- st_sample(sf_poly, size = 10000)
  # k-means clustering
  points <- do.call(rbind, st_geometry(points_rnd)) %>%
    as_tibble() %>% setNames(c("lon","lat"))
  k_means <- kmeans(points, centers = n_areas)
  # Create voronoi polygons
  voronoi_polys <- dismo::voronoi(k_means$centers, ext = sf_poly)
  # Clip to sf_poly
  crs(voronoi_polys) <- wgs84 ## hardcoding crs
  voronoi_sf <- st_as_sf(voronoi_polys)
  equal_areas <- st_intersection(voronoi_sf, sf_poly)
  #equal_areas$area <- st_area(equal_areas)
  return(equal_areas)
}
#### splitting the polygons and plotting ####

## split polygons for each Bundesländer based on number of colors provided
pol_areas  <- lapply(seq_len(nrow(Germany)), function(i) 
        if (length(unlist(Germany[i,]$COLORS)) == 1) {Germany[i,]} 
        else {split_poly(Germany[i,], length(unlist(Germany[i,]$COLORS)))}) 

## combine the splited polygons to one sf object
bind_rows(pol_areas) %>% 
  rowwise() %>% 
  mutate(Color = ifelse(is.na(id), COLORS, COLORS[id])) -> mapdata_deu 

## plot
plot(mapdata_deu[,"geometry"],
     col = mapdata_deu$Color, 
     bg = "#aadaff", border = NA)
plot(Germany[,"geometry"],
     col = NA, 
     bg = NA, border = "black", add = T)

/></p>
<p><sup>Created on 2024-04-01 with <a href=”https://reprex.tidyverse.orgreprex v2.0.2




我并不十分肯定你为每个国家(即联邦议院)所希望的颜色,但下面的法典确实做了工作。 您可按要求修改<代码>Colors。

library(sf)
library(sp)
library(raster)
library(rgdal)

Germany <- getData(country = "Germany", level = 1) 

Colors <- c("#D7191C", "#FDAE61", "#FFFFBF", "#ABDDA4",
            "#D7191C", "#FDAE61", "#ABDDA4", "#D7191C", 
            "#FDAE61", "#FFFFBF", "#ABDDA4", "#2B83BA",
            "#D7191C", "#FDAE61", "#ABDDA4", "#D7191C")

plot(Germany, 
     col = Colors[as.numeric(as.factor(Germany$NAME_1))], 
     border = "white", bg = "#aadaff")

https://i.imgur.com/v8Uy8Ij.png” alt=">

Created on 2024-03-24 with reprex v2.0.2.

问题回答

我不是整个想法的大fan(尽管我从技术角度感兴趣),也是为了改变总体的地貌,我必须承认——而且我也不是<代码>{ggplot2}的电力用户。 因此,或许可以将以下做法作为一种蓝图,但也许需要你根据你们的需要进行一些细微调整,特别是在模式的密度和间隔方面(见您,柏林、汉堡、布雷曼)。

然而,正如评论所示,我使用<代码>geom_sf_pattern(>,从{ggpattern},采用多科全线的脱光线模式。

为了开始,我们首先需要每个国家的肤色:

library(geodata)
#> terra 1.7.71
library(sf)
#> Linking to GEOS 3.11.2, GDAL 3.8.2, PROJ 9.3.1; sf_use_s2() is TRUE
library(RColorBrewer)
library(ggplot2)
library(ggpattern)

# get administrative levels for Germany
ger <- geodata::gadm("Germany", path = tempfile()) |> 
  sf::st_as_sf()

# from how many different colors do you want to choose?
n <- 5
colors_base <- brewer.pal(n, "Spectral")

# pick 1 to 4 colors per state
set.seed(42)
colors <- sample(colors_base, size = sample.int(n-1, size = 1)) |> replicate(n = 16, expr = _)
names(colors) <- ger[["NAME_1"]]

colors
#> $`Baden-Württemberg`
#> [1] "#2B83BA"
#> 
#> $Bayern
#> [1] "#D7191C"
#> 
#> $Berlin
#> [1] "#ABDDA4" "#FDAE61"
#> 
#> $Brandenburg
#> [1] "#D7191C" "#ABDDA4"
#> 
#> $Bremen
#> [1] "#ABDDA4" "#D7191C" "#2B83BA"
#> 
#> $Hamburg
#> [1] "#ABDDA4" "#FDAE61"
#> 
#> $Hessen
#> [1] "#FFFFBF" "#D7191C"
#> 
#> $`Mecklenburg-Vorpommern`
#> [1] "#FFFFBF"
#> 
#> $Niedersachsen
#> [1] "#2B83BA" "#FFFFBF" "#D7191C" "#ABDDA4"
#> 
#> $`Nordrhein-Westfalen`
#> [1] "#FDAE61" "#ABDDA4" "#FFFFBF" "#2B83BA"
#> 
#> $`Rheinland-Pfalz`
#> [1] "#FDAE61"
#> 
#> $Saarland
#> [1] "#FFFFBF" "#2B83BA" "#FDAE61" "#ABDDA4"
#> 
#> $Sachsen
#> [1] "#ABDDA4" "#2B83BA" "#FDAE61" "#FFFFBF"
#> 
#> $`Sachsen-Anhalt`
#> [1] "#ABDDA4"
#> 
#> $`Schleswig-Holstein`
#> [1] "#ABDDA4"
#> 
#> $Thüringen
#> [1] "#FDAE61" "#FFFFBF"

The following snippet was arbitrary copied from the ggpattern 为使多彩工作发挥作用。

multicolor_stripe_pattern <- function(params, boundary_df, aspect_ratio, 
                                      legend = FALSE) {
  args <- as.list(params)
  args <- args[grep("^pattern_", names(args))]
  
  args$pattern_colour <- strsplit(args$pattern_colour, ",")[[1]]
  args$pattern_fill <- strsplit(args$pattern_fill, ",")[[1]]
  
  args$pattern <- "stripe"
  args$x <- boundary_df$x
  args$y <- boundary_df$y
  args$id <- boundary_df$id
  args$prefix <- ""
  
  do.call(gridpattern::patternGrob, args)
}

options(ggpattern_geometry_funcs = list(multicolor_stripe = multicolor_stripe_pattern))

最后和相关的部分可能远远没有说服力,但这是我非常冷静地处理这个问题: 简单地在各州进行渗透,选择相关的肤色和期望的称谓。 显然需要一些调整,因为我对此并不感到完全满意,但如果你认为这只是概念的证明,整个想法似乎在发挥作用(我认为,这仍然是一种可怕的视化方式)。

# initialize data without aesthetics
gg <- ggplot() +
  geom_sf(data = ger, aes())


# iterate over your states and fill the polygons according to specifications
for (i in 1:dim(ger)[1]) {
  
  # just fill the polygon, if there is only one color
  if (length(colors[[i]]) == 1) {
    
    gg <- gg + 
      geom_sf(data = ger[i, ], fill = colors[[i]])
    
    # use stripe pattern, if there are only two colors
  } else if (length(colors[[i]]) == 2) {
    
    gg <- gg + 
      geom_sf_pattern(data = ger[i, ], 
                      mapping = aes(fill = colors[[i]][1]),
                      pattern = "stripe",
                      pattern_fill = colors[[i]][2],
                      pattern_density = 0.5,
                      pattern_spacing = 0.02)
    
    # use multicolor stripe pattern, if there are more than two colors
  } else if (length(colors[[i]]) > 2) {
    
    n_cols <- length(colors[[i]])
    
    gg <- gg + 
      geom_sf_pattern(data = ger[i, ], 
                      mapping = aes(fill = colors[[i]][1]),
                      pattern = "multicolor_stripe",
                      pattern_fill = colors[[i]][2:n_cols] |> paste0(collapse = ","),
                      pattern_density = 0.5,
                      pattern_spacing = 0.02)
  }
}

gg

></p>
<p><sup>Created on 2024-04-06 with <a href=”https://reprex.tidyverse.orgreprex v2.1.0





相关问题
How to plot fitted model over observed time series

This is a really really simple question to which I seem to be entirely unable to get a solution. I would like to do a scatter plot of an observed time series in R, and over this I want to plot the ...

REvolution for R

since the latest Ubuntu release (karmic koala), I noticed that the internal R package advertises on start-up the REvolution package. It seems to be a library collection for high-performance matrix ...

R - capturing elements of R output into text files

I am trying to run an analysis by invoking R through the command line as follows: R --no-save < SampleProgram.R > SampleProgram.opt For example, consider the simple R program below: mydata =...

R statistical package: wrapping GOFrame objects

I m trying to generate GOFrame objects to generate a gene ontology mapping in R for unsupported organisms (see http://www.bioconductor.org/packages/release/bioc/vignettes/GOstats/inst/doc/...

Changing the order of dodged bars in ggplot2 barplot

I have a dataframe df.all and I m plotting it in a bar plot with ggplot2 using the code below. I d like to make it so that the order of the dodged bars is flipped. That is, so that the bars labeled "...

Strange error when using sparse matrices and glmnet

I m getting a weird error when training a glmnet regression. invalid class "dgCMatrix" object: length(Dimnames[[2]]) must match Dim[2] It only happens occasionally, and perhaps only under larger ...

Generating non-duplicate combination pairs in R

Sorry for the non-descriptive title but I don t know whether there s a word for what I m trying to achieve. Let s assume that I have a list of names of different classes like c( 1 , 2 , 3 , 4 ) ...

Per panel smoothing in ggplot2

I m plotting a group of curves, using facet in ggplot2. I d like to have a smoother applied to plots where there are enough points to smooth, but not on plots with very few points. In particular I d ...

热门标签