2015-09-10 2 views
2

Я пытаюсь наложить многострочный сюжет (используя базовую графику в R) над одним панельным графиком карты. Мульти-панель сюжет выглядит следующим образом:Оверлейный многопанельный сюжет на одном участке

multi-panel plot

... и я хочу, чтобы наложить это на карте (построенной с использованием пакета карт).

Мой код выглядит следующим образом:

# Blank plot for map 
plot(1, 1, type="n", xlab="", ylab="", axes=F, 
    xlim=c(-39,-35.5),ylim=c(-55,-54)) 
# Plot map 
map("worldHires", regions="Falkland Islands:South Georgia",col="#BFBFBF", 
    fill=F, add=T, bg="#7F7F7F", lwd=0.05) 
# Start overplotting 
par(new=T) 
par(mfrow=c(2,3)) 
par(mar=c(0,0,0,0),oma=c(5,7,1,0)) 
hist(~yy$l.class[yy$strat=="SR"], breaks=classes, main="",xlab="",ylab="", 
    col=cols[1], border=cols[1], probability=T, ylim=c(0,0.18), 
    bg=rgb(1,1,1,0)) 

Однако, как только я сюжет этой первой гистограмму, я получаю следующее:

plot fail

Как вы можете видеть, первая гистограмма вместо нанесенный на последнюю панель многопанельной компоновки. Когда я пытаюсь построить дальнейшие гистограммы, откроется новое устройство.

Я предполагаю, что это как-то связано с моими вызовами par() после построения карты? Любой совет?

ответ

2

Без воспроизводимого вопроса я покажу один способ сделать это с помощью общих данных. Вам придется адаптировать его к своей работе.

Multi-plot можно сделать с помощью par(mfrow=c(2,3)), и хотя это просто, это самый ограничительный. Другие варианты включают layout(...) (для этого, я думаю, это не сработает) и par(fig=...) (вот что я здесь использую). Разумная стартовая ссылка - here.

Начну с вашей картой (NB: пожалуйста, укажите необходимые библиотеки с кодом):

library(maps) 
library(mapdata) 
par(fig=c(0,1,0,1))      # force full-device plot 
plot(1, 1, type="n", xlab="", ylab="", axes=F, 
    xlim=c(-39,-35.5),ylim=c(-55,-54)) 
map("worldHires", regions="Falkland Islands:South Georgia",col="#BFBFBF", 
    fill=F, add=T, bg="#7F7F7F", lwd=0.05) 

Далее я создал матрицу, которая будет использоваться для определения региона участка, имитируя расположение вы определили с помощью par(mfrow=c(2,3)):

xs <- seq(0, 1, len=4) 
ys <- seq(0, 1, len=3) 
m <- merge(cbind(head(xs, n=-1), tail(xs, n=-1)), 
      cbind(head(ys, n=-1), tail(ys, n=-1)), 
      by=NULL) 
##  V1.x  V2.x V1.y V2.y 
## 1 0.0000000 0.3333333 0.0 0.5 
## 2 0.3333333 0.6666667 0.0 0.5 
## 3 0.6666667 1.0000000 0.0 0.5 
## 4 0.0000000 0.3333333 0.5 1.0 
## 5 0.3333333 0.6666667 0.5 1.0 
## 6 0.6666667 1.0000000 0.5 1.0 

par(fig=...) занимает левую и правую (х) и нижние и верхние (у) проценты. В первой строке m указано, что следующий график будет содержать от 0 до 33% по горизонтали и от 0 до 50% по вертикали от экрана (то есть в левом нижнем углу). Первый вызов сюжета не обязательно требует вызова par(fig=...), но мне нравится его там, чтобы я сбросил макет сюжета, когда я переделаю сюжет. Он должен либо опустить new=TRUE, либо использовать new=FALSE, чтобы быть явным (возможно, это хорошо в разы).

Далее я просто заберу несколько графиков. Эта часть - моя изобретательная часть, но она показывает, как она используется. Программное определение m и его использование ниже не являются полностью необходимыми; вы можете легко определить каждый вызов par(fig=...) вручную. Несмотря на это, использование простой сетки 2х3 графиков также не является необходимым, и этот метод позволяет разместить гистограммы в значимых местах на карте. (Это, очевидно, может быть сделано программно, но полностью зависит от вас и ваших данных.)

columns <- c('mpg', 'hp', 'drat', 'wt', 'qsec') 
for (i in 1:5) { 
    par(fig=unlist(m[i,]), new=TRUE) 
    col <- names(mtcars)[i] 
    hist(mtcars[[col]], col=1+i, main=col) 
} 

enter image description here

+0

Это прекрасно работает! Спасибо, r2evans. – niafall

+0

Будем предупреждать, что использование 'par (fig = ...)' примерно так же ручно-трудовое, как вы можете получить ... он может легко получить dorked, если он несовместим. * С большой силой приходит большая ответственность * :-) – r2evans

+0

Возможно, вы уже знаете, что, напротив, 'par (mfrow = ...)', это заполнение слева направо и (по-разному) * снизу- Вверх*. Это достаточно легко исправить, например, 'rev (ys)'. – r2evans

2

Самым простым решением является вручную установить par(mfg = c(1,1)).Это говорит R, чтобы поместить следующий (вспомогательный) график в первый слот mfrow-индуцированный макет на текущей странице.

Так, например, вы можете просто сделать что-то вроде этого:

library(maps) 
library(mapdata) 

## Set up the background map 
plot.new() 
par(fig = c(0,1,0,1)) 
plot.window(xlim=c(-39,-35.5),ylim=c(-55,-54)) 
map("worldHires", regions="Falkland Islands:South Georgia", col="#BFBFBF", add=TRUE) 

## Set up a grid of subplots areas 
par(mfrow = c(2, 3), mfg = c(1, 1))   ## **Key is to set mfg=c(1,1)** 

## Fill grid with subplots 
hist(mtcars[["mpg"]], main="mpg", col=2) 
hist(mtcars[["hp"]], main="hp", col=3) 
hist(mtcars[["cyl"]], main="cyl", col=4) 
plot.new()         ## Skip plotting into this cell 
hist(mtcars[["disp"]], main="dip", col=5) 
hist(mtcars[["drat"]], main="drat", col=6) 

enter image description here

Вы должны установить par(mfg=...) это явно потому, что для m матрицу с размерностью n макет, по умолчанию R - установить par(mfg=c(m,n)); который устанавливает вещи так, что следующий сюжет войдет в первый слот макета на следующей странице - не то, что вы хотите в этом случае.

+0

О, дерьмо, это здорово! Это невероятно полезно в повседневной обработке, а не просто одноразовом, тем самым уменьшая необходимость в моем ручном решении par (fig). ('par (fig)' по-прежнему полезно, когда требуется нетривиальная компоновка.) – r2evans

+0

@ r2evans - Ха-ха. Рад, что вы оценили его так сильно, как я. Это стоит того, чтобы написать это! И да, я согласен: 'par (fig = ...)' et al. обеспечивают максимальную гибкость (сначала следует «layout()», а затем, наконец, «par (mfcol = ...)» и «par (mfrow = ...)»). –

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