我正在尝试创建包含一些负值和大部分为正值的 map 。我拥有的代码(如下所示)会生成正确的 map ,但是图例未居中于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)
最佳答案
TL; DR
看来r-mapview
的at
变量不能处理超过10个中断。往下看:
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))))
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)
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)
但是,如果我们实际上具有负值(
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)
解:
因此,我解决问题的方法是在
foo
数据中添加两行,其中-max_val
和+max_val
基本上是multipolygons
,没有面积和长度(aka点),因此我们的数据集的镜像值约为零,因此mapview
将生成“平衡”图例,但是用户不会在 map 上看到这些点,因为它们的面积为零。再次在下面查找骇客的实现。 (请注意,如果需要,您可以在数据边界之外的某个位置添加这些虚拟点/多面体,然后将默认缩放比例设置为实际数据,这是不必要的,因为正如我所说,这些虚拟点不可见)。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 package(v0.3.0)创建于2019-06-25