Разделите землю и воду, используя два градиента в ggplot - PullRequest
3 голосов
/ 25 апреля 2019

Я пытаюсь получить два отдельных градиента для земли и воды на карте.Я могу получить градиент воды (первая цифра), но не землю.

Как я могу установить серый градиент для земли в этом коде (аналогично рисунку 2 ниже)?

Пример данных

library(marmap)
library(ggplot2)

greys <- c(grey(0.6), grey(0.93), grey(0.99))

# Get map data
bat <- getNOAA.bathy(-68, -51, -48, -39, res = 1, keep = TRUE)

Создание графика с градиентом воды

autoplot(bat, geom = c("raster", "contour"), colour = "white", size = 0.1) + 
  scale_fill_gradientn(limits = c(-6600, 0), colors = c("steelblue4", "#C7E0FF")) +
  NULL

enter image description here

Я пытался установить различные пределы в scale_fill_gradientn, но без особой удачи:

autoplot(bat, geom = c("raster", "contour"), colour = "white", size = 0.1) + 
  scale_fill_gradientn(limits = c(min(bat), max(bat)), 
                       colors = c("steelblue4", "#C7E0FF", greys)) +
  NULL

Требуемый выход (выполняется с использованием функций построения графика R)

plot(bat, image = TRUE, land = TRUE, lwd = 0.1, bpal = list(c(0, max(bat), greys), c(min(bat), 0, blues)))
plot(bat, lwd = 0.8, deep = 0, shallow = 0, step = 0, add = TRUE) # highlight coastline

enter image description here

Ответы [ 2 ]

4 голосов
/ 25 апреля 2019

Подход с cut и scale_fill_manual:

Это намного сложнее, чем ответ @ Z.Lin (с которым я лично согласился бы), но этот метод потенциально дает вам больше контроля, а geom_raster сюжет довольно быстро.

Я сделал все это вручную, но вы можете представить себе функцию, которая принимает вектор высот и количество желаемых разрывов, а затем разбивает вектор на набор категориальных разрывов иделает соответствующие этикетки.Это то, что sp::spplot() делает по умолчанию с непрерывными полями, и использует nbreaks = 16.Вам нужно будет сделать разрыв нулевой отметки, чтобы различить сушу и океан.

Вот общая идея, которую можно развить.

# convert to raster, then data frame
library(raster)
d <- as.raster(bat)
d <- as.data.frame(d, xy=TRUE)

# upper and lower elevation bounds
z <- max(d$layer)
a <- min(d$layer)

# breaks and labels for color scale
brks <- c(a, 1000, 500, 0, -500, -1000, -2000, -3000, -4000, -5000, z)
labs <- c("> 1000", "500:1000", "0:500", "-500:0", "-1000:-500", "-2000:-1000",
          "-3000:-2000", "-4000:-3000", "-5000:-4000", "< -6514")
d$bin <- cut(d$layer, breaks = brks, labels = labs)
d <- d[!is.na(d$bin), ] # filter sneaky NA values

library(colormap)
gr   <- colormap(colormaps$greys, nshades = 10)[4:6]
bl   <- colormap(colormaps$velocity_blue, nshades = 13)[3:9]
cols <- c(bl, gr)

# plot
ggplot(d, aes(x, y, fill = bin)) +
  geom_raster() +
  scale_fill_manual(values = cols, limits = labs, labels = rev(labs)) +
  theme_minimal() +
  labs(fill = "Elevation (ft)")

enter image description here

2 голосов
/ 25 апреля 2019

Может как то так?Диапазон значений заполнения получается из проверки summary(fortify.bathy(bat)) для диапазона z.

autoplot(bat, geom = c("raster", "contour"), colour = "white", size = 0.1) + 
  scale_fill_gradientn(values = scales::rescale(c(-6600, 0, 1, 1500)),
                       colors = c("steelblue4", "#C7E0FF", "grey50", "grey80"))

plot

Примечание: я использовал c("grey50", "grey80")в качестве диапазона значений серого здесь, но, конечно, вы можете изменить это в зависимости от ваших требований.

...