Skip to content

draw.key; getting grobWidth to respect fontfamily="mono"

4 messages · Benjamin Tyner, Paul Murrell

#
Hello

Within my panel function, I am using draw.key to create a custom key for 
each panel. I'm trying to use grobWidth to calculate the correct width 
for the viewport, but it appears to be disregarding the fontfamily when 
computing the width. Attached is an example; any ideas what I'm doing wrong?

Many thanks
Ben
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: grobWidth.R
URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20120906/cfe0d2f8/attachment.pl>
#
Update: seems one way to skin this cat is to add

   gp = gpar(fontfamily="mono")

to the viewport() call itself. If anyone has any suggestions for a 
robust way to extract this piece information from the key grob itself 
(it's nested several levels deep), I'm all ears.

Thanks
Ben
3 days later
#
Hi
On 07/09/12 09:35, Benjamin Tyner wrote:
I'm going to try to blame 'lattice' for this problem (because it appears 
to be generating "strwidth" units for the text entries in the key rather 
than "grobwidth" units [so the 'gp' settings on the text grobs are being 
ignored when widths are calculated]).  (Though 'lattice' is probably 
doing that to avoid using packGrob() and being further slowed down by 
'grid'!)

However, since you are already deep enough into 'grid' to be using 
viewports and grobWidth() yourself, I suspect that you could get what 
you want by avoiding draw.key() altogether.  You could generate a text 
grob yourself (based on your 'GOFlist'), directly query it for its 
width, build a viewport based on that width (similar to the viewport 
that you are already creating), push the viewport and draw the grob.
Something like this ...

GOFgrob <- function(x) {
     textGrob(c(x$title, x$text$label),
              x=.5, y=unit(.5, "npc") + unit(1:-1, "lines"),
              gp=gpar(fontfamily=c("sans", "mono", "mono")))
}

plot <- xyplot(actual + forecast ~ yyyymm | cond,
                data = Data,
                layout = c(1,2),
                type = "l",
                panel = function(x,y,GOFlist,...){
                  panel.xyplot(x,y,...)
                  pn <- panel.number()
                  key <- GOFgrob(GOFlist[[pn]])
                  vp <- viewport(x = 1,
                                 y = 1,
                                 width = grobWidth(key) +
                                         unit(2, "lines"),
                                 height = grobHeight(key) +
                                          unit(1, "lines"),
                                 just = c("right","top")
                                 )
                  pushViewport(vp)
                  grid.draw(key)
                  grid.rect()
                  popViewport()
                },
                GOFlist = GOFlist
                )

Hope that helps.

Paul

  
    
3 days later
#
Many thanks Paul, that is a nifty way to do it.

Regards
Ben
Paul Murrell wrote: