Как уменьшить пространство между сюжетом и границей для географических карт? - PullRequest
0 голосов
/ 22 октября 2018

Я пытаюсь построить батиметрическую карту северо-востока США, используя библиотеку marmap.Следующий код загружает правильный экстент, но когда я строю карту, у меня появляется пустое пространство между границей и картой в верхней / нижней или левой / правой частях карты.Это также происходит при экспорте графиков.Если я перетаскиваю размер экрана средства просмотра графика, график корректируется, и я могу удалить почти все пустое пространство, но я буду запускать этот сценарий в цикле, так что решить эту проблему таким способом не практично.Из-за цикла я также не могу жестко закодировать любые измерения в графике, потому что он будет меняться для каждого нового экстента.Как я могу установить границу участка, чтобы соответствовать степени батиметрии?

library(marmap)
library(maps)

atl<- getNOAA.bathy(-80.93645,-41.61417,30.2 ,60.905 ,resolution=4)
blues <- colorRampPalette(c("darkblue", "cyan"))
greys <- colorRampPalette(c(grey(0.4),grey(0.99)))

plot(atl, image = TRUE, land = TRUE, n=0,
     bpal = list(c(0, max(atl), greys(100)),
                 c(min(atl), 0, blues(100))))
map(database= "state", col="black", fill=FALSE, add=TRUE)
text(x=state.center$x, y=state.center$y, state.abb, cex=0.5)

enter image description here

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Вот предложение с использованием обходного пути.Идея состоит в том, чтобы преобразовать объект bathy в raster объект, а затем создать график, используя levelplot из rasterVis, который правильно соответствует области построения в растровом экстенте.Обратите внимание, что использование растра позволяет иметь определенный размер пикселя и, следовательно, правильное соотношение ширины и высоты, которое, по-видимому, не достигается при методе marmap::plot.

library(raster)
library(rasterVis)

r <- marmap::as.raster(atl)

state <- map('state', plot = FALSE) 
state <- data.frame(lon = state$x, lat = state$y) 

state.lab <- data.frame(lon = state.center$x, lat = state.center$y, 
                        label = state.abb)

# you can remove the color legend by adding colorkey = FALSE in levelplot() 
levelplot(r, 
          at = c(seq(min(atl), 0, length.out = 100), 
                 seq(0, max(atl), length.out = 100)[-1]),
          col.regions = c(blues(100), greys(100)), 
          margin = FALSE) +
  xyplot(lat ~ lon, state, type = 'l', 
         col = 'black') +
  xyplot(lat ~ lon, data = state.lab,
         panel = function(y, x, ...) {
         ltext(x = x, y = y, labels = state.lab$label, cex = 0.75)
         })

enter image description here

0 голосов
/ 22 октября 2018

Такое поведение вызвано аргументом asp plot.bathy().По умолчанию он установлен как asp = 1, чтобы гарантировать, что шкалы на обеих осях одинаковы (один градус долготы равен одному градусу широты).Неприятным последствием этого значения по умолчанию являются белые полосы, появляющиеся либо на левой / правой сторонах графика, либо на верхней / нижней сторонах в зависимости от размеров батиметрической карты и устройства построения графика.

ИтакЯ полагаю, у вас есть 2 варианта:

  1. Если вы не возражаете против слегка искаженной перспективы, вы можете установить asp = NA в своем вызове на plot.bathy()
  2. Если вы хотитечтобы иметь правильное соотношение сторон, но при этом необходимо использовать размер по умолчанию для вашей области печати, вам необходимо загрузить батиметрическую область, которая охватывает всю область построения вашего активного устройства.Например, вы можете вызвать plot.bathy() один раз, чтобы создать график «по умолчанию», а затем использовать par("usr"), чтобы определить пределы батиметрии, необходимые для заполнения всей области построения.Затем вы должны загрузить вторую батиметрию с соответствующими диапазонами по долготе и широте.Что, возможно, нежелательно.

Вот как будет выглядеть код для второго варианта:

atl <- getNOAA.bathy(-80.93645, -41.61417, 30.2, 60.905, resolution = 4)
blues <- colorRampPalette(c("darkblue", "cyan"))
greys <- colorRampPalette(c(grey(0.4), grey(0.99)))

plot(atl, image = TRUE, land = TRUE, n = 0,
     bpal = list(c(0, max(atl), greys(100)),
                 c(min(atl), 0, blues(100))))

coord <- par("usr")
atl2 <- getNOAA.bathy(coord[1], coord[2], coord[3], coord[4], res = 4)
plot(atl2, image = TRUE, land = TRUE, lwd = 0.2,
     bpal = list(c(0, max(atl2), greys(100)),
                 c(min(atl2), 0, blues(100))))
map(database = "state", col = "black", fill = FALSE, add = TRUE)
text(x = state.center$x, y = state.center$y, state.abb, cex = 0.5)

enter image description here

Полагаю, решение, предложенное Романом Луштриком, тоже работает, но неудобно оставлять белые полосы видимыми с обеих сторон графика.

В качестве отступления, если у вас много батиметрических областей дляplot, вам, возможно, следует рассмотреть возможность использования аргумента keep = TRUE для getNOAA.bathy(), чтобы избежать запросов к серверам NOAA каждый раз, когда вам необходимо повторно выполнить свой код (и загрузка локальных данных намного быстрее, чем удаленных).И вы также можете загрузить раз и навсегда глобальный 4Go ETOPO1 и использовать subset.bathy(), чтобы, ну, в общем, поднастроить необходимую вам батиметрию для каждого графика.

...