2014-02-18 3 views
3

Я начал использовать функцию Rдля построения карт. Я заметил, что при изменении размера окна графика изображение не масштабируется, чтобы заполнить окно. Как я могу получить изображение карты для автоматического изменения размера большего или меньшего размера, в зависимости от того, насколько сильно я перетаскиваю свое окно?Как изменить размеры карт, чтобы заполнить окно графика?

Я использую R версии 3.0.2 на MacOS.

Например, вот карта, где я перетащил окно сюжета поменьше и больше. Обратите внимание, что размер изображения карты не изменяется.

library(maps) 
map("state") 

enter image description here

enter image description here

enter image description here

С другой стороны, обычная plot() команда делает размер графики по размеру окна.

plot(1:100, 201:300) 

enter image description here

enter image description here

enter image description here

+1

Вы можете указать размер окна графика перед вызовом графика, например dev.new (width = 3, height = 3) – user20650

ответ

6

Это займет немного работы, но путем преобразования maps объекта в SpatialPolygonsDataFrame, а затем spplot() «ING, что вы можете получить динамически изменяя размер карты.

FWIW, я подозреваю, что это работает лучше, потому что spplot() основан на сетке (через решетки), а сетка графическая система поддерживает гораздо более сложные способы обработки размеров в пределах объектов участка, чем делает базовую графическую систему R в.

library(maps) 
library(maptools) ## For map2SpatialPolygons() 

## Convert data from a "maps" object to a "SpatialPolygonsDataFrame" object 
mp <- map("state", fill = TRUE, plot = FALSE) 
SP <- map2SpatialPolygons(mp, IDs = mp$names, 
          proj4string = CRS("+proj=longlat +datum=WGS84")) 
DATA <- data.frame(seq_len(length(SP)), row.names = names(SP)) 
SPDF <- SpatialPolygonsDataFrame(SP, data = DATA) 

## Plot it 
spplot(SPDF, col.regions = "transparent", colorkey = FALSE, 
     par.settings = list(axis.line = list(col = "transparent"))) 

Вот несколько скриншотов, чтобы показать, что он работает:

enter image description here

enter image description here

+0

Спасибо. Это похоже на большую работу для такой простой проблемы. – stackoverflowuser2010

+0

Добро пожаловать. Это немного работы, но опять же я сделал большую часть этого для вас;). Если вы переносите большую часть кода выше в функцию, вызов его может быть таким же простым, как делать что-то вроде 'plotMap2SPDF (mp)'. –

+1

Хм. Похоже, нужен вызов map() для включения 'fill = T'. В противном случае вы получите сообщение об ошибке. 'Ошибка в map2SpatialPolygons (mp, IDs = mp $ names, proj4string = CRS (" + proj = longlat + datum = WGS84 ")): карта и идентификаторы отличаются по длине' – stackoverflowuser2010

3

Хочу отметить, что Джош обеспечил приемлемое решение этой проблемы, но это может быть полезно понять , почемуmap() имеет поведение, которое вы описываете. По существу это сводится к map(), устанавливая размер области для построения графика на основе текущего размера &. Соотношение сторон устройства (фигурная область более конкретно) в момент рисования.

Таким образом, одно решение без преобразования в другой формат, как хорошо демонстрирует Джош, - это просто перерисовать карту после, вы перемасшлили устройство до нужного размера. Вы можете избежать некоторых догадок, выполнив пару вычислений на основе соотношения сторон par("usr"), а затем установите для устройства ширину, совместимую с этим соотношением сторон.

Наверное, больше хлопот, чем решение Джоша, но оно объясняет поведение. Более подробное описание проблемы приведено ниже.


Причина, по которой обращается карта не «заполнить» устройство (до указанных краев) связана с кодом в map() установив размер области черчения, чтобы иметь отношение конкретного аспекта на основе размер устройства и т. д. Полученная область построения имеет такой размер, что она помещается внутри устройства, но сохраняет правильное соотношение сторон, поэтому может не полностью заполнять его.

Ключевой фрагмент кода заключается в следующем:

 else { 
      par(mar = mar) 
      p <- par("fin") - as.vector(matrix(c(0, 1, 1, 
       0, 0, 1, 1, 0), nrow = 2) %*% par("mai")) 
      par(pin = p) 
      p <- par("pin") 
      p <- d * min(p/d) 
      par(pin = p) 
      d <- d * myborder + ((p/min(p/d) - d)/2)/aspect 
      usr <- c(xrange, yrange) + rep(c(-1, 1), 2) * 
       rep(d, c(2, 2)) 
      par(usr = usr) 
     } 

с d определены чуть раньше, как:

 d <- c(diff(xrange), diff(yrange)) * (1 + 2 * myborder) * 
      aspect 

(для примера, вы даете). Вторая строка ветви else получает текущий размер области фигуры в дюймах. Область фигуры - это размер на устройстве области, содержащей поля и участок участка, но не любой внешний край. Фактически, если нет активного внешнего поля, этот код захватывает размер устройства (и делает корректировку). Затем этот результат используется для установки размера области построения графика, который обновляется.

Предполагается, что цель состоит в том, чтобы взять размер текущей области фигуры и использовать ее для обновления региона, в который нарисована карта. Размер этой области печати в этом смысле контролируется с помощью соотношения сторон устройства; если вы начинаете с широкого, но короткого окна, то в области вычисленного графика не будет необходимости использовать всю доступную ширину (если бы соотношение сторон было неправильным), и, следовательно, область графика будет иметь размер, меньший, чем доступное пространство ,

Относительно того, почему это не обновляется при изменении размеров окна, а именно потому, что в разводного время размер черчения области устанавливают абсолютно в дюймов. Если вы измените размер устройства, размер области печати останется прежним, и, следовательно, карта будет обрезана, если вы достаточно урезаете устройство или используете меньше и меньше места на устройстве, если вы увеличите его.

+0

Знаете ли вы какие-либо функции построения на основе базовой графики, которые динамически изменяют размер области фигуры, сохраняя при этом ее аспект? Я пытаюсь думать о любом, но я рисую пробел. Если они есть, было бы интересно посмотреть, как они это достигают. (** grid ** * в конечном счете * делает это через аргумент 'respect =' для 'grid ::: grid.layout()'.) –

+0

Мне было интересно, может ли установка параметра 'asp', возможно, не лучший способ чтобы решить это для 'map()', но не слишком об этом подумал, я был просто заинтригован, почему сюжет не был перемасштабирован. –

+1

Но есть ли параметр asp для базовой графики? (Я вроде думал, что есть, но не вижу этого в '? Par'.) –

Смежные вопросы