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

Jeff Stevens stev0175 at gmail.com
Sun Apr 10 13:50:47 CEST 2011

```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)
}
)

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