JAponte
JAponte

Reputation: 1538

How to specify different ylim values for each panel in xyplot?

I'm trying to specify different limits for the y axes of each panel in xyplot, but the results are inconsistent with different data subsets.

The problem arises when I define the panel slicing with two different grouping variables, and one or more subgroups has no data value.

It seems that xyplot is skipping axis preparation for panels with no data.

Here is an example:

library(lattice)

df1<-data.frame(
          x=rep(1, 4),y=rep(1, 4), cat1=c('A','B','A','B'), cat2=c('1','1','2','2'))
df2<-data.frame(
          x=rep(1, 3),y=rep(1, 3), cat1=c('A','B','A'), cat2=c('1','2','1'))

myFun <-  function(df)  {
  print(
      xyplot(y ~ x | cat1 * cat2,
      data=df,
      scales=list(
          y=list(
              relation='free', 
              limits=rep(list(c(0,10), c(-100,10)) , 2)))
  ) )
}

myFun(df1)
myFun(df2)

df1 has data available on each subgroup, while df2 doesn't. When I call myFun(df1), it works as expected, but myFun(df2) throws the following error.

>   myFun(df2)
Warning message:
In limitsFromLimitlist(have.lim = have.ylim, lim = ylim, relation = y.relation,  :
  number of items to replace is not a multiple of replacement length

I would like my function to work for any subset of the original data frame, so it is very likely that one or more subgroups will have no data value.

In case that there is no data value for a subgroup, I still would like to see the y axis with the right limits.

Any ideas of how to achieve this?

Upvotes: 3

Views: 2992

Answers (1)

Josh O&#39;Brien
Josh O&#39;Brien

Reputation: 162311

Since the problem occurs only for factor-combinations having no data, you can side-step it by 'supplementing' your data with an additional point for each factor-combination. As long as the additional points fall outside the plotted regions, their only effect will be to ensure that the panel and prepanel preparations needed to set the appropriate y-limits are triggered.

This works, and is simpler than mucking about with prepanel.default.xyplot(), prepanel.null(), limits.and.aspect(), limitsFromLimitList() and whatever other functions are involved in setting the limits for panels with no data!

Here's an example:

## Create a supplementary data frame with one data point for each factor level
dummy <- with(df2, expand.grid(cat1=levels(cat1), cat2=levels(cat2)))
dummy <- data.frame(x=1, y=1e6, dummy)

## Append it to your data frame
df2 <- rbind(df2, dummy)

## Now try plotting it
myFun(df2)

enter image description here

Upvotes: 3

Related Questions