# [R] Adding text labels to lattice plots with multiple panels

Jeff Stevens stev0175 at gmail.com
Sun Apr 10 21:19:35 CEST 2011

```Many thanks, Peter.  This works brilliantly, and I prefer to have the
labels assigned outside of panel function as well.

Cheers,
Jeff

On Sun, Apr 10, 2011 at 5:18 PM, Peter Ehlers <ehlers at ucalgary.ca> wrote:
> On 2011-04-10 04:50, Jeff Stevens wrote:
>>
>> Hi Peter,
>>
>> Thanks for the solutions.  The only problem now is that I have
>> duplicate values in my labels that are removed by the duplicated
>> function.  Perhaps a better example of the labels vector would be:
>> lab<- c(1,2,4,4,6,6)
>>
>> Your first version would maintain the second 4 (because they are in
>> different panels) but leave a blank for the second 6.
>> 1 2 4 4 6
>> The second version removes the second 4 and 6.
>> 1 2 4   6
>>
>> The following works, but it is not very efficient for my full data set
>> with six levels of f1, two levels of f2, and 64 replicates of each of
>> these combinations.
>>
>> bwplot(dv ~ f1 | f2, data = df, ylim = c(0.5, 1),
>>  panel = function(x, y, ..., subscripts) {
>>    lab<<- df\$lab[subscripts]
>>    lab[c(2:3,5:6,8:9)]<<- ""
>>    panel.bwplot(x, y,  ...)
>>    panel.text(x, 0.55, labels = lab)
>>  }
>> )
>
> Good point; I hadn't thought of that. Now I realize that a
> solution that fiddles with the labels inside the panel
> function is likely to be less efficient anyway. So let's
> adjust the labels to be printed before we do the bwplot()
> call. What's needed is to set to blanks the labels that
> are duplicates because they correspond to duplicated
> (f1,f2) combinations.
>
> ## lab is the current vector of labels;
>  names(df)
>  #[1] "f1"   "f2"   "dv"   "lab"
>
>  df <- transform(df,
>        lab2 = ifelse(duplicated(df[, c("f1","f2")]), "", lab))
>
> ## now use lab2 in bwplot()
>  bwplot(dv ~ f1 | f2, data = df, ylim = c(0.5, 1),
>  panel = function(x, y, ..., subscripts) {
>    lab <- df\$lab2[subscripts]   # note the lab2
>    panel.bwplot(x, y,  ...)
>    panel.text(x, 0.55, labels = lab)
>  }
>  )
>
> Peter Ehlers
>
>>
>> Thanks,
>> Jeff
>>
>>
>> On Sat, Apr 9, 2011 at 7:52 PM, Peter Ehlers<ehlers at ucalgary.ca>  wrote:
>>>
>>> On 2011-04-09 06:21, Dennis Murphy wrote:
>>>>
>>>> Hi:
>>>>
>>>> One hopes that there is a more elegant solution than this bit of
>>>>>
>>>>
>>>> f1<- c(rep(c(rep("a", 3), rep("b", 3), rep("c", 3)), 2))
>>>> f2<- c(rep("A", 9), rep("B", 9))
>>>> dv<- c(0.9, 0.8, 0.85, 0.6, 0.65, 0.7, 0.8, 0.85, 0.8, 0.95, 0.85,
>>>>  0.9, 0.65, 0.7, 0.75, 0.85, 0.9, 0.85)
>>>> df<- data.frame(f1, f2, dv)
>>>> df\$lab<- rep(1:6, each = 3)
>>>>
>>>> df\$lab2<- ''
>>>> df\$lab2[seq(1, 16, by = 3)]<- 1:6        # adapt to your situation -
>>>> seq(1,
>>>> nrow(df) - 63, by = 64), perhaps
>>>>
>>>> bwplot(dv ~ f1 | f2, data = df, ylim = c(0.5, 1),
>>>>  panel = function(x, y, ..., subscripts) {
>>>>    lab<- df\$lab2[subscripts]
>>>>    panel.bwplot(x, y,  ...)
>>>>    panel.text(x, 0.55, labels = lab)
>>>>  }
>>>> )
>>>>
>>>> Alternatively, panel.text() takes an alpha = argument; for example,
>>>>
>>>> bwplot(dv ~ f1 | f2, data = df, ylim = c(0.5, 1),
>>>>  panel = function(x, y, ..., subscripts) {
>>>>    lab<- df\$lab[subscripts]
>>>>    panel.bwplot(x, y,  ...)
>>>>    panel.text(x, 0.55, labels = lab, alpha = 0.5)
>>>>  }
>>>> )
>>>>
>>>> You could toy with the value of alpha until something acceptable
>>>> emerges.
>>>> But as I said, there is probably a better solution and I'm happy to be
>>>> educated if there is.
>>>
>>> Here's a slight variation on your first solution which doesn't
>>> require the data to be appropriately sorted, using your df:
>>>
>>>  bwplot(dv ~ f1 | f2, data = df, ylim = c(0.5, 1),
>>>  panel = function(x, y, ..., subscripts) {
>>>    lab<- df\$lab[subscripts]
>>>    lab[duplicated(lab)]<- ""
>>>    panel.bwplot(x, y,  ...)
>>>    panel.text(x, 0.55, labels = lab)
>>>  }
>>>  )
>>>
>>> and another variation which sets the text positions to NA for
>>> all but the first pass through the panel.text() function:
>>>
>>>  bwplot(dv ~ f1 | f2, data = df, ylim = c(0.5, 1),
>>>  panel = function(x, y, ..., subscripts) {
>>>    at.y<- rep(0.55, nrow(df))
>>>    is.na(at.y)<- which(duplicated(df\$lab))
>>>    panel.bwplot(x, y,  ...)
>>>    panel.text(x, at.y[subscripts], labels = df\$lab[subscripts])
>>>  }
>>>  )
>>>
>>> I think that the alpha argument is too one-off, i.e. dependent on
>>> how many levels in the boxplot.
>>>
>>> Peter Ehlers
>>>
>>>>
>>>> HTH,
>>>> Dennis
>>>>
>>>> On Sat, Apr 9, 2011 at 4:56 AM, Jeff
>>>>
>>>>> Hi,
>>>>>
>>>>> Thanks for the work around, Dennis.  My actual data set has 64
>>>>> replicates for each factor level combination (rather than the 3 in the
>>>>> example), so the overplotting is quite messy.  Any ideas on how to
>>>>> avoid the overplotting?
>>>>>
>>>>> Jeff
>>>>>
>>>>>
>>>>> On Fri, Apr 8, 2011 at 7:32 PM, Dennis Murphy<djmuser at gmail.com>
>>>>>  wrote:
>>>>>>
>>>>>> Hi:
>>>>>>
>>>>>> After a number of false starts, I finally consulted Deepayan's book
>>>>>> and
>>>>>
>>>>> the
>>>>>>
>>>>>> example on p. 73, suitably adapted, yielded a solution. Add a variable
>>>>>
>>>>> for
>>>>>>
>>>>>> the labels and then...
>>>>>>
>>>>>> df\$lab<- rep(1:6, each = 3)
>>>>>> bwplot(dv ~ f1 | f2, data = df, ylim = c(0.5, 1),
>>>>>>  panel = function(x, y, ..., subscripts) {
>>>>>>    lab<- df\$lab[subscripts]
>>>>>>    panel.bwplot(x, y,  ...)
>>>>>>    panel.text(x, 0.55, labels = lab)
>>>>>>  }
>>>>>> )
>>>>>>
>>>>>> If you look closely, you'll see that each label is overplotted three
>>>>>
>>>>> times.
>>>>>>
>>>>>> A similar plot in ggplot2  would be
>>>>>>
>>>>>> library(ggplot2)
>>>>>> ggplot(df, aes(x = f1, y = dv)) + geom_boxplot() +
>>>>>>     geom_text(aes(x = as.numeric(f1), lab = lab), y = 0.55, alpha =
>>>>>> 0.5)
>>>>>
>>>>> +
>>>>>>
>>>>>>     facet_wrap( ~ f2) + ylim(0.5, 1)
>>>>>>
>>>>>> The alpha argument in geom_text() is designed to mitigate the
>>>>>
>>>>> overplotting
>>>>>>
>>>>>> effect somewhat.
>>>>>>
>>>>>> HTH,
>>>>>> Dennis
>>>>>>
>>>>>>
>>>>>> On Fri, Apr 8, 2011 at 5:32 AM, Jeff Stevens<stev0175 at googlemail.com>
>>>>>> wrote:
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> I am trying to add text to the bottom of a lattice bwplot with
>>>>>>> multiple panels.  I would like to add a label below each boxplot, but
>>>>>>> the labels do not come from the data.  I've tried the following,
>>>>>>> code:
>>>>>>>
>>>>>>> f1<- c(rep(c(rep("a", 3), rep("b", 3), rep("c", 3)), 2))
>>>>>>> f2<- c(rep("A", 9), rep("B", 9))
>>>>>>> dv<- c(0.9, 0.8, 0.85, 0.6, 0.65, 0.7, 0.8, 0.85, 0.8, 0.95, 0.85,
>>>>>>> 0.9, 0.65, 0.7, 0.75, 0.85, 0.9, 0.85)
>>>>>>> df<- data.frame(f1, f2, dv)
>>>>>>> lab<- c(1, 2, 3, 4, 5, 6)
>>>>>>>
>>>>>>> bwplot(dv ~ f1 | f2, data = df, ylim = c(0.5, 1),
>>>>>>>  panel = function(x, y, ...) {
>>>>>>>    panel.bwplot(x, y, ...)
>>>>>>>    panel.text(x, 0.55, labels = lab)
>>>>>>>  }
>>>>>>> )
>>>>>>>
>>>>>>> I have two problems.  First, the label values are writing over one
>>>>>>> another.  I wrote a horrible hack (below) that fixes that problem,
>>>>>>> but
>>>>>>> I would like to know if there are better/more flexible ways to do
>>>>>>> this.
>>>>>>>
>>>>>>> bwplot(dv ~ f1 | f2, data = df, ylim = c(0.5, 1),
>>>>>>>  panel = function(x, y, ...) {
>>>>>>>    x2<- as.factor(c("a", "b", "c"))
>>>>>>>    panel.bwplot(x, y, ...)
>>>>>>>    panel.text(x2, 0.55, labels = lab)
>>>>>>>  }
>>>>>>> )
>>>>>>>
>>>>>>> Second, when using the horrible hack the first values are repeated in
>>>>>>> the second panel.  How do I display the correct values in the second
>>>>>>> panel?  The subscripts argument seems to do the trick when the labels
>>>>>>> come from the data, but how do I get the proper values when the
>>>>>>> labels
>>>>>>> come from outside of the data?
>>>>>>>
>>>>>>>
>>>>>>> Many thanks,
>>>>>>> Jeff
>>>>>>>
>>>>>>> ______________________________________________
>>>>>>> R-help at r-project.org mailing list
>>>>>>> https://stat.ethz.ch/mailman/listinfo/r-help
>>>>>>> http://www.R-project.org/posting-guide.html
>>>>>>> and provide commented, minimal, self-contained, reproducible code.
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Jeff Stevens
>>>>> Center for Adaptive Behavior and Cognition
>>>>> Max Planck Institute for Human Development
>>>>> Lentzealle 94
>>>>> 14195 Berlin, Germany
>>>>>
>>>>
>>>>        [[alternative HTML version deleted]]
>>>>
>>>> ______________________________________________
>>>> R-help at r-project.org mailing list
>>>> https://stat.ethz.ch/mailman/listinfo/r-help