[R] trellis/lattice: How to plot 4 panels with the same x-scale but different y-scales?

Marius Hofert m_hofert at web.de
Fri May 7 10:29:13 CEST 2010


Dear Felix,

the split and position argument can indeed be used (see below). But one has to manually adjust the position argument for the last plot (bottom right) in order to be aligned with the second (top right). This issue does not appear in the "panel function" approach. 
As you can see from the code below, it is possible to put some text under the x-axis of a panel, but the positioning depends on the scale of the y-axis... hmm... no perfect solution.

Cheers,

Marius

## print idea
myplot <- function(x,y,z,xlab,ylab){
        xyplot(y~x|z,type="l",aspect=1,
                xlab=xlab,ylab=ylab,
                strip = function(...) strip.default(...),
                scales=list(alternating=c(1,1),tck=c(1,0))
                )
}
print(myplot(1:2,1:2,"variable 1","x label","y label"),split=c(1,1,2,2),more=TRUE)
print(myplot(1:2,2:1,"variable 2","x label","y label"),split=c(1,2,2,2),more=TRUE)
print(myplot(1:2,c(1,-1),"variable 3","x label","y label"),split=c(2,1,2,2),more=TRUE)
print(myplot(1:2,c(-2000,2000),"variable 4","x label","y label"),split=c(2,2,2,2),more=FALSE)

## panel function
library(lattice)
x=c(1,2,1,2,1,2,1,2)
y=c(1,2,2,1,1,-1,-2000,2000)
z=c(1,1,2,2,3,3,4,4) # panel number
xyplot(y~x|z,type="l",aspect=1,layout=c(2,2),
       scales=list(y=list(rot=0),relation="free",alternating=c(1,1),tck=c(1,0)),
       par.settings = list(clip=list(panel=FALSE),
       layout.widths = list(axis.panel = 2,xlab=4,ylab=4),
       layout.heights = list(axis.panel = 2)),
       panel=function(...){
               panel.xyplot(...,col=1)
               panel.text(x=unit(1.5,"npc"),y=unit(-1.7,"npc"),"x axis")
       }    
)


On 2010-05-07, at 09:54 , Felix Andrews wrote:

> If it is enough to have two y labels on the left side and two x label
> along the bottom, you can specify xlab/ylab as vectors. Rather than
> drawing different xlabs or ylabs for all panels in a grid, you would
> typically use strips to label the panels.
> 
> By the way, you could use the 'split' or 'position' arguments to
> print.trellis to achieve the same result as your grid layout.
> 
> 
> On 7 May 2010 01:52, Marius Hofert <m_hofert at web.de> wrote:
>> Dear Deepayan,
>> 
>> Thank you very much for your quick help.
>> 
>> I played a bit around and came up with two methods of plotting
>> a "matrix of plots" on a single page (see the code below). The first you know
>> from my earlier postings. For this method I have the following questions:
>> 1) Is it possible to have different x- and y-labels for each of the panels
>> (as in the second plot)?
>> 2) Is it possible to rotate the y-axis ticks in each panel by -90 degrees
>> (as in the second plot)?
>> For the second method:
>> 3) Is it possible reduce/control the space between the panels?
>> 4) Is it possible to align the panels according to their "frame"? [the panels of
>> the variables 2 and 4 are not properly aligned as the labels for the latter need
>> more space than the ones of the former.]
>> 
>> Many thanks,
>> 
>> Marius
>> 
>> 
>> library(lattice)
>> library(grid)
>> 
>> ## panel function
>> library(lattice)
>> x=c(1,2,1,2,1,2,1,2)
>> y=c(1,2,2,1,1,-1,-2000,2000)
>> z=c(1,1,2,2,3,3,4,4) # panel number
>> xyplot(y~x|z,type="l",aspect=1,layout=c(2,2),
>>       scales=list(relation="free",alternating=c(1,1),tck=c(1,0)),
>>       par.settings = list(layout.widths = list(axis.panel = 2),
>>       layout.heights = list(axis.panel = 2)),
>>       panel=function(...){
>>               panel.xyplot(...,col=1)
>>       }
>> )
>> 
>> ## grid idea
>> myplot <- function(x,y,z,xlab,ylab){
>>        xyplot(y~x|z,type="l",aspect=1,
>>                xlab=xlab,ylab=ylab,
>>                strip = function(...) strip.default(...),
>>                scales=list(alternating=c(1,1),tck=c(1,0))
>>                )
>> }
>> grid.newpage()
>> pushViewport(viewport(layout=grid.layout(2,2)))
>> pushViewport(viewport(layout.pos.row=1,layout.pos.col=1))
>>    print(myplot(1:2,1:2,"variable 1","x label","y label"),newpage=FALSE)
>> popViewport(1)
>> pushViewport(viewport(layout.pos.row=1,layout.pos.col=2))
>>  print(myplot(1:2,2:1,"variable 2","x label","y label"),newpage=FALSE)
>> popViewport(1)
>> pushViewport(viewport(layout.pos.row=2,layout.pos.col=1))
>>    print(myplot(1:2,c(1,-1),"variable 3","x label","y label"),newpage=FALSE)
>> popViewport(1)
>> pushViewport(viewport(layout.pos.row=2,layout.pos.col=2))
>>  print(myplot(1:2,c(-2000,2000),"variable 4","x label","y label"),newpage=FALSE)
>> popViewport(1)
>> 
>> 
>> 
>> On 2010-05-06, at 15:09 , Deepayan Sarkar wrote:
>> 
>>> On Thu, May 6, 2010 at 6:24 PM, Marius Hofert <m_hofert at web.de> wrote:
>>>> Thanks, Deepayan.
>>>> 
>>>> Is it at least possible to increase the space between the panels in the following plot?:
>>>> 
>>>> library(lattice)
>>>> x=rep(c(1,2,3),4) # x values
>>>> y=1:12 # y values
>>>> z=rep(1:4,each=3) # panel number
>>>> xyplot(y~x|z,type="l",aspect=1,layout=c(2,2),
>>>>       scales=list(relation="free",alternating=c(1,1),tck=c(1,0)),
>>>>       panel=function(...){
>>>>               panel.xyplot(...,col=1)
>>>> 
>>>>       }
>>>> )
>>> 
>>> Sure, add
>>> 
>>> par.settings = list(layout.widths = list(axis.panel = 2))
>>> 
>>> (similarly layout.heights for vertical gap).
>>> 
>>> -Deepayan
>>> 
>>>> 
>>>> On 2010-05-06, at 13:53 , Deepayan Sarkar wrote:
>>>> 
>>>>> On Thu, May 6, 2010 at 12:16 PM, Marius Hofert <m_hofert at web.de> wrote:
>>>>>> Dear R experts,
>>>>>> 
>>>>>> I have four plots I would like to plot attached to each other (in panels).
>>>>>> All plots have the same x-scale, but different y-scales. The example below shows
>>>>>> pretty much what I would like to have, except that for the two plots in the
>>>>>> "second column" (of this 2x2 plot-matrix), I would like to have the y-ticks
>>>>>> shown on the right side such that the four plot panels are attached to each other/glued
>>>>>> together. How can I achieve this?
>>>>> 
>>>>> There is no easy way.
>>>>> 
>>>>> For the first step of a difficult way, see ?axis.default
>>>>> 
>>>>> -Deepayan
>>>>> 
>>>>> 
>>>>>> I found a solution for a 2x1 matrix in the R-help archive, but this problem here is different.
>>>>>> 
>>>>>> Cheers,
>>>>>> 
>>>>>> Marius
>>>>>> 
>>>>>> Ps: I guess the "scales=..." should somehow go inside the panel function, so that
>>>>>> the panel number tells the "alternating"-argument where it has to print the ticks.
>>>>>> 
>>>>>> library(lattice)
>>>>>> x=rep(c(1,2,3),4) # x values
>>>>>> y=1:12 # y values
>>>>>> z=rep(1:4,each=3) # panel number
>>>>>> xyplot(y~x|z,type="l",aspect=1,layout=c(2,2),
>>>>>>        scales=list(y=list(relation="free"),alternating=c(1,1),tck=c(1,0)),
>>>>>>        panel=function(...){
>>>>>>                panel.xyplot(...,col=1)
>>>>>> 
>>>>>>        }
>>>>>> )
>>>>>> ______________________________________________
>>>>>> R-help at r-project.org mailing list
>>>>>> https://stat.ethz.ch/mailman/listinfo/r-help
>>>>>> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
>>>>>> and provide commented, minimal, self-contained, reproducible code.
>>>>>> 
>>>> 
>>>> 
>> 
>> ______________________________________________
>> R-help at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
>> and provide commented, minimal, self-contained, reproducible code.
>> 
> 
> 
> 
> -- 
> Felix Andrews / 安福立
> Postdoctoral Fellow
> Integrated Catchment Assessment and Management (iCAM) Centre
> Fenner School of Environment and Society [Bldg 48a]
> The Australian National University
> Canberra ACT 0200 Australia
> M: +61 410 400 963
> T: + 61 2 6125 4670
> E: felix.andrews at anu.edu.au
> CRICOS Provider No. 00120C
> -- 
> http://www.neurofractal.org/felix/



More information about the R-help mailing list