Suzana
Suzana

Reputation: 21

Equal size for multiple panels with different y-axis scales in lattice

I have multiple variables of a time series that differ in their scales. I want to plot each variable over time in a single-page, and each plot will have its own y-axis. Seems to be easy, but I have a symmetry problem, since the plots that have higher values for y-axis were flattened to the right compared with the ones with smaller values for y-axis. Another problem with the panel size appeared when I decided to keep the x-axis only in two plots. These panels became more flattened than the others.

I'm relatively new to lattice and I have searched a lot with no success. First I tried to arrange the plots with grid.arrange, but I can't modify a specific panel with this function. So I tried to arrange plots with print and then use panel.widths and panel.heights. but it doesn't give the exactly equal size for all panels. Any suggestions to get multiple panels with equal sizes considering different y-axis and x-axis presence/absence? Example below:

#Data
a<-c(1058.2557,821.2002,1004.5201,296.8243,374.3730,746.0718,954.6511,264.7352)
b<-c(100,60,40,36,42,32,42,32)
c<-c(116.610418,164.462337,47.862511,12.613479,4.253702,39.868584,21.591731,6.037917)
d<-c(4,10,3,2,1,5,11,13)
e<-c(20,30,10,50,21,60,20,70)
est1<-c("16:00","19:00","22:00","01:00","04:00","07:00","10:00","13:00")
newest1<-factor(est1,levels=unique(est1))

mysettings<-list(layout.heights=list(top.padding=-1,bottom.padding=-1),
layout.widths=list(right.padding=-2))

plo1<-barchart(a~newest1,scales=list(x=list(alternating=0)),par.settings=mysettings)
plo2<-barchart(b~newest1,scales=list(x=list(alternating=0)),par.settings=mysettings)
plo3<-barchart(c~newest1,scales=list(x=list(alternating=0)),par.settings=mysettings)
plo4<-barchart(d~newest1,scales=list(x=list(rot=45)),par.settings=mysettings)
plo5<-barchart(e~newest1,scales=list(x=list(rot=45)),par.settings=mysettings)

trellis.device(windows, height=6, width=7)
print(plo1, split=c(1,1,2,3),more=T)
print(plo2, split=c(2,1,2,3),more=T)
print(plo3, split=c(1,2,2,3),more=T)
print(plo4, split=c(2,2,2,3),more=T)
print(plo5, split=c(1,3,2,3),more=F)

Upvotes: 2

Views: 2088

Answers (2)

MrFlick
MrFlick

Reputation: 206232

Generally you wouldn't layout related plots like that in lattice. You would typically use a grouping variable. For this to work, you need all your data in one data.frame

dd <- data.frame(make.groups(a=a,b=b,c=c,d=d,e=e), newest1=newest1)

And to make things look a bit nicer i'll define a custom axis function

axis.yout<- function(side, ...) { 
    if(side %in% c("left", "right")) {
        if (panel.number() %% 2 == which(c("right","left")==side)-1) {
            panel.axis(side = side, outside =TRUE)
        }
    } else {
        axis.default(side = side, ...)
    }
}

now I plot with

barchart(data~newest1 | which, dd, layout=c(2,3), 
    scales=list(alternating=T, y=list(relation="free")),
    par.settings=list(layout.widths=list(right.padding=5, axis.panel = c(1, 0))),
    axis=axis.yout
)

which result in

enter image description here

which all share a common x-axis while allowing for free and independently labeled y-axis. And the spacing/passing is all consistent because we used a single call to lattice. Normally you wouldn't bother with a custom axis function like this, but when the scales relation is "free", lattice gets a bit grumpy about alternating labels.

Upvotes: 4

Henrik
Henrik

Reputation: 67778

I am sure someone will post a nice lattice solution. Meanwhile, you may consider a ggplot alternative.

library(reshape2)
library(ggplot2)

First, collect your vectors in a data frame, and reshape data from a wide to a long format:

df <- data.frame(newest1, a, b, c, d, e)   
df2 <- melt(df, id.var = "newest1")

Plot the data in separate facets, one facet for each of the original vectors (which in the melted data ("df2") appear as different levels of the "variable" variable). We allow independent ("free") y axis scales in each facet:

ggplot(data = df2, aes(x = newest1, y = value)) +
  geom_bar(stat = "identity") +
  facet_wrap(~ variable, scales = "free_y") +
  theme(axis.text.x  = element_text(angle = 45, vjust = 1, hjust = 1))

enter image description here

Upvotes: 1

Related Questions