2014-11-19 4 views
4

Я хочу сделать сюжет, состоящий из нескольких графиков, состоящих из нескольких графиков, скажем, сетки 5x2 с тремя графиками в каждой ячейке. Чтобы быть более точным, мне нужна не только одна фигура, но и несколько способов использования функции построения графика в одном сюжете.Вложенные макеты в R

Я написал функцию, которая использует макет для складывания графиков, с общей осью во внешнем крае. Мне действительно нужно это для функций seqIplot и seqdplot из пакета TraMineR, но насколько я понимаю, проблема не связана с ними, так что вот минимальный рабочий пример с barplot.

stackedplot <- function(data){ 
    layout(matrix(c(1:3), nrow=3)) 
    par(mar=c(0,0,0,0), oma=c(4,1,1,1), mgp=c(3,0.5,0), cex=1) 
    barplot(data[[1]], axes=F, xlab="", ylab="", horiz=TRUE) 
    barplot(data[[2]], axes=F, xlab="", ylab="", horiz=TRUE) 
    barplot(data[[3]], axes=F, xlab="", ylab="", horiz=TRUE) 
    axis(1, at=c(0:10)/10, outer=TRUE) 
    mtext("Label", line=2, side=1) 
} 
stackedplot(list(1:10, 10:1, rep(1,10))) 

То, что я хотел бы сделать, это то использовать что-то вроде макета снова и использовать stackedplot для решеток макета, т.е. что-то вроде этого (что, конечно, не работает):

layout(matrix(c(1:2), nrow=1)) 
stackedplot(list(1:10, 10:1, rep(1,10))) 
stackedplot(list(rep(1,10), 1:10, 10:1)) 

Я попытался split.screen, без успеха:

split.screen(c(1,2)) 
screen(1) 
stackedplot(list(1:10, 10:1, rep(1,10))) 
screen(2) 
stackedplot(list(rep(1,10), 1:10, 10:1)) 
close.screen(all = TRUE) 

Я также попытался пакет сетки, но, видимо, он не совместим с базовыми графикой.

grid.newpage() 
pushViewport(viewport(x=0, y=0, width=0.5, height=1, 
          default.units="native")) 
print(stackedplot(list(1:10, 10:1, rep(1,10))), newpage=FALSE) 
pushViewport(viewport(x=0.5, y=0, width=0.5, height=1, 
         default.units="native")) 
print(stackedplot(list(rep(1,10), 1:10, 10:1)), newpage=FALSE) 
+0

AFAIK, вложенными 'layout's не представляется возможным. И 'split.screen' документально не смешивается с' layout'. – Roland

+0

Если проблема связана с TraMineR, вы можете использовать seqIplot (group = NULL, withlegend = FALSE), а TraMineR не будет вызывать команду layout. –

+0

Спасибо, Маттиас.Проблема, однако, кажется, не связана напрямую с TraMineR, но поставляется со всеми (базовыми) графиками. В настоящий момент пакет gridBase выглядит многообещающим при построении «вложенных макетов». – Satu

ответ

2

После дополнительных исследований и некоторой помощи я теперь отвечаю на свой вопрос, если это было бы полезно кому-то другому.

Вложенные макеты могут быть созданы с помощью пакета grid, который может использоваться для базовой графики с использованием пакета gridBase. Функция для сложенных графиков записывается следующим образом.

library(grid) 
library(gridBase) 

stackedplot <- function(data, main=""){ 

    top.vp <- viewport(layout=grid.layout(nrow=5, ncol=1, 
             heights=unit(c(3, 1, 1, 1, 5), 
                c("lines", "null", "null", "null", "lines"))), 
        width=unit(0.9, "npc")) 

    title <- viewport(layout.pos.row=1, layout.pos.col=1, name="title") 
    p1 <- viewport(layout.pos.row=2, layout.pos.col=1, name="plot1") 
    p2 <- viewport(layout.pos.row=3, layout.pos.col=1, name="plot2") 
    p3 <- viewport(layout.pos.row=4, layout.pos.col=1, name="plot3") 
    xaxis <- viewport(layout.pos.row=5, layout.pos.col=1, name="xaxis") 

    splot <- vpTree(top.vp, vpList(title, p1, p2, p3, xaxis)) # Defining the hierarchy of the viewports 
    pushViewport(splot) # Creating viewports for plotting with the definitions of splot 

    upViewport() # Navigating up in the viewport tree 
    downViewport("plot1") # Navigating down in the viewport tree, searching for viewport "plot1" 
    grid.rect() # Plotting a rectangle (borders for the viewport) 
    par(plt=gridPLT(), new=TRUE) # Taking the dimensions of the viewport for a base graphics plot 
           # Adding plot to an existing plot 
    barplot(data[[1]], axes=FALSE, xlab="", ylab="", horiz=TRUE) 

    upViewport() 
    downViewport("plot2") 
    grid.rect() 
    par(plt=gridPLT(), new=TRUE) 
    barplot(data[[2]], axes=FALSE, xlab="", ylab="", horiz=TRUE) 

    upViewport() 
    downViewport("plot3") 
    grid.rect() 
    par(plt=gridPLT(), new=TRUE) 
    barplot(data[[3]], xlab="", ylab="", horiz=TRUE) 

    upViewport() 
    downViewport("xaxis") 
    grid.text("X label", y = unit(2, "lines")) 

    upViewport() 
    downViewport("title") 
    grid.text(main, y = unit(1, "lines")) 

    upViewport(2) 
} 

Функция первым описывает окно просмотра (90% от ширины окна), который разделен на 5x1 сетки видовыхов с различной высотой. Каждому видовому экрану в сетке присваивается имя, которое впоследствии можно вызвать. Дерево видовых экранов (splot) описано с помощью vpTree, которое определяет иерархическую структуру видовых экранов. После описания видовых экранов они фактически подготовлены для построения с pushViewport.

Теперь каждый названный видовой экран сначала открывается, а затем открывается для построения с upViewport (который поднимается в дереве видового экрана) и downViewport (который ищет требуемое окно просмотра вниз в дереве видовой области).

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

После запрошенных участков upViewport(2) используется для перехода к корню (2 видовых экранов в иерархии).

Теперь функцию stackedplot можно вызвать несколько раз в другой сетке следующим образом.

opar <- par(no.readonly=TRUE) # Saving graphical parameters 
plot.new() # Needed for par(new=TRUE) in stackedplot() 

multitop.vp <- viewport(layout=grid.layout(1,2), width = unit(0.95, "npc")) 
pl1 <- viewport(layout.pos.col=1, layout.pos.row=1, name="A") 
pl2 <- viewport(layout.pos.col=2, layout.pos.row=1, name="B") 
vpall <- vpTree(multitop.vp, vpList(pl1,pl2)) 
pushViewport(vpall) 

upViewport() 
downViewport("A") 
stackedplot(data=list(1:10,10:1,rep(10,10)),main="A") 

upViewport() 
downViewport("B") 
stackedplot(data=list(10:1,rep(10,10),1:10),main="B") 

upViewport(2) 
par(opar) # Returning the graphical parameters saved earlier 

enter image description here

+2

более новой и, возможно, полезной альтернативой является пакет gridGraphics, где 'grid.echo' создает сетную версию базовой графики. – baptiste