4

我正在尝试创建一个包含一些负值和主要是正值的地图。我拥有的代码(如下所示)生成正确的地图,但图例不以 0 为中心(即白色不在 0 处,而更多的负值是更深的红色,更多的正值是蓝色)。无论数据集中的值如何,如何将调色板更改为以 0 为中心?

代码:

library(tidyverse)
library(sf)
library(mapview)

palfunc <- function (n, alpha = 1, begin = 0, end = 1, direction = 1) 
{
colors <- RColorBrewer::brewer.pal(11, "RdBu")
if (direction < 0) colors <- rev(colors)
colorRampPalette(colors, alpha = alpha)(n)
}


foo <- franconia %>% mutate(foo = rnorm(n()) + 2)

max_val = max(abs(foo$foo), na.rm = T)
n_val = max( length(unique(keep(foo$foo, ~.x > 0))),
         length(unique(keep(foo$foo, ~.x < 0))))
at = lattice::do.breaks(endpoints = c(-max_val, max_val), nint = 2 * n_val + 1)
p <- mapView(foo, zcol = 'foo', layer.name = "Example", col.regions = palfunc, at = at)
4

1 回答 1

1

TL;博士

似乎无法在其变量r-mapview中处理超过 10 个中断。at往下看:

library(tidyverse)
library(sf)
library(mapview)

palfunc <- function (n, alpha = 1, begin = 0, end = 1, direction = 1) 
{
  colors <- RColorBrewer::brewer.pal(11, "RdBu")
  if (direction < 0) colors <- rev(colors)
  colorRampPalette(colors, alpha = alpha)(n)
}

set.seed(92)
foo <- franconia %>% mutate(foo = rnorm(n()) + 2)

max_val = max(abs(foo$foo), na.rm = T)
n_val = max( length(unique(keep(foo$foo, ~.x > 0))),
             length(unique(keep(foo$foo, ~.x < 0))))
  • 10 次休息:
at_10 = lattice::do.breaks(endpoints = c(-max_val, max_val), nint = 10)
mapView(foo, zcol = 'foo', layer.name = "Example", col.regions = palfunc, at = at_10)

  • 11 次休息:
at_11 = lattice::do.breaks(endpoints = c(-max_val, max_val), nint = 11)
mapView(foo, zcol = 'foo', layer.name = "Example", col.regions = palfunc, at = at_11)

  • 当数据限制实际上反映在 0 左右时:

但是,如果我们实际上有负值 ( min(values) ≈ max(values)),则默认情况下图例将以 0 为中心:

library(tidyverse)
library(sf)
library(mapview)

palfunc <- function (n, alpha = 1, begin = 0, end = 1, direction = 1) 
{
  colors <- RColorBrewer::brewer.pal(11, "RdBu")
  if (direction < 0) colors <- rev(colors)
  colorRampPalette(colors, alpha = alpha)(n)
}

set.seed(92)
foo <- franconia %>% mutate(foo = c((rnorm((n()-1)) + 2), -4))

max_val = max(abs(foo$foo), na.rm = T)
n_val = max( length(unique(keep(foo$foo, ~.x > 0))),
             length(unique(keep(foo$foo, ~.x < 0))))

mapView(foo, zcol = 'foo', layer.name = "Example", col.regions = palfunc)

解决方案:

因此,我解决您的问题的 hacky 方法是在您的数据中添加两行foo-max_val它们+max_val基本上multipolygons没有面积和长度(又名点),因此我们的数据集具有零附近的镜像值,因此mapview会生成“平衡”图例,但是用户会在地图上看不到这些点,因为它们的面积为零。再次查看下面的hacky实现。(ps如果你愿意,你可以在数据边界之外的某个地方添加那些虚拟点/多边形,然后将默认缩放设置为你的实际数据,这是不必要的,因为正如我所说,这些虚拟点不可见)。

library(tidyverse)
library(sf)
library(mapview)

palfunc <- function (n, alpha = 1, begin = 0, end = 1, direction = 1) 
{
  colors <- RColorBrewer::brewer.pal(11, "RdBu")
  if (direction < 0) colors <- rev(colors)
  colorRampPalette(colors, alpha = alpha)(n)
}

set.seed(92)
foo <- franconia %>% mutate(foo = (rnorm((n())) + 2))

max_val = max(abs(foo$foo), na.rm = T)
n_val = max( length(unique(keep(foo$foo, ~.x > 0))),
             length(unique(keep(foo$foo, ~.x < 0))))

#creating a dummy polygon which all of its boundaries point are the same
a_dummy_m <- matrix(c(10.92582, 49.92508, 10.92582, 49.92508,
                    10.92582, 49.92508, 10.92582, 49.92508,
                    10.92582, 49.92508),ncol=2, byrow=TRUE)

a_dummy_p <- st_multipolygon(list(list(a_dummy_m), list(a_dummy_m), list(a_dummy_m)))

#mimicking foo structure to make a point with negative value of absolute maximum
dummy_neg <- structure(list(NUTS_ID = "N/A", SHAPE_AREA = st_area(a_dummy_p),
              SHAPE_LEN = st_length(a_dummy_p), CNTR_CODE = structure(1L, 
                                                .Label = "N/A", class = "factor"), 
              NAME_ASCI = structure(1L, .Label = c("N/A"), class = "factor"), 
              geometry = structure(list(a_dummy_p), class = c("sfc_MULTIPOLYGON", "sfc"),
              precision = 0, bbox = st_bbox(a_dummy_p), 
              crs = structure(list(epsg = 4326L, 
                     proj4string = "+proj=longlat +datum=WGS84 +no_defs"), 
                     class = "crs"), n_empty = 0L), 
                     district = "N/A", foo = -max_val), sf_column = "geometry", 
              agr = structure(c(NUTS_ID = NA_integer_, SHAPE_AREA = NA_integer_, 
                     SHAPE_LEN = NA_integer_, CNTR_CODE = NA_integer_, 
                     NAME_ASCI = NA_integer_, district = NA_integer_, 
                     foo = NA_integer_), 
             .Label = c("constant", "aggregate", "identity"), class = "factor"),
              row.names = 1L, class = c("sf", "data.frame"))


#and now making the data with positive value 
dummy_pos <- dummy_neg %>% mutate(foo=max_val)

#row binding those with `foo` dataset to make a new dataset which is "balanced"
foo2 <- rbind(dummy_neg, dummy_pos,foo)

mapView(foo2, zcol = 'foo', layer.name = "Example", col.regions = palfunc)

reprex 包(v0.3.0)于 2019 年 6 月 25 日创建

于 2019-06-25T22:53:04.670 回答