Масштабирование легенды Mapview - PullRequest
3 голосов
/ 03 апреля 2019

Я пытаюсь создать карту, содержащую некоторые отрицательные значения и в основном положительные значения. Приведенный ниже код (приведенный ниже) создает правильную карту, однако легенда не центрируется в 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)

1 Ответ

1 голос
/ 26 июня 2019

TL; DR

Кажется, что 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)

Решение:

Итак, мой хакерский способ решения вашей проблемы - добавить две строки в ваш foo набор данных с -max_val и +max_val, которые в основном multipolygons без области и длины (или точки), поэтому наш набор данных отразился значения около нуля и, следовательно, mapview будет генерировать «сбалансированную» легенду, однако пользователь не увидит эти точки на карте, поскольку их площадь равна нулю. Посмотрите ниже для, опять же, хакерской реализации. (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)

Создан в 2019-06-25 пакетом Представить (v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...