Re: [R] packGrob and dynamic resizing
Hi I could speculate, but what would be more useful would be some profiling results. If you could try Rprof() on your examples (and post me the results directly), that would provide some useful information to see if some speed-ups could be made. Paul baptiste auguie wrote: Hi, I just tried a fourth variant, closer to what ggplot2 uses (I think): to each grob is assigned a viewport with row and column positions (in my example during their construction, with ggplot2 upon editing), and they're all plotted in a given grid.layout. The timing is poor compared to pushing and upping viewports (twice as long). Why would that be? All the best, baptiste (the full, self-contained comparison file is attached, run as: R --vanilla -f comparison.r ) # below is version 4 only makeContentInVp - function(d){ content - as.character(unlist(c(d))) nc - ncol(d) nr - nrow(d) n2nm - function(nr, nc){ expand.grid(seq(1, nr), seq(1, nc)) } vp.ind - n2nm(nr, nc) textii - function(d, gp=gpar(), name=content-label-){ function(ii) textGrob(label=d[ii], gp=gp, name=paste(name, ii, sep=), vp=viewport(layout.pos.row=vp.ind[ii, 1], layout.pos.col=vp.ind[ii, 2])) } makeOneLabel - textii(d=content, gp=gpar(col=blue)) lg - lapply(seq_along(content), makeOneLabel) list(lg=lg, nrow=nrow(d), ncol=ncol(d)) } ## table4 uses grobs that already have a viewport assigned table4 - function(content){ padding - unit(4, mm) lg - content$lg ## retrieve the widths and heights of all textGrobs wg - lapply(lg, grobWidth) # list of grob widths hg - lapply(lg, grobHeight) # list of grob heights ## concatenate this units widths.all - do.call(unit.c, wg) # all grob widths heights.all - do.call(unit.c, hg)#all grob heights ## matrix-like operations on units to define the table layout widths - colMax.units(widths.all, content$ncol) # all column widths heights - rowMax.units(heights.all, content$nrow) # all row heights vp - viewport(layout=grid.layout(content$nrow,content$ncol, w=widths+padding, h=heights+padding)) grid.draw(gTree(children=do.call(gList, lg), vp=vp)) } # uncomment for timing d - head(iris) #d - iris content2 - makeContentInVp(d) # grid.newpage() # system.time(table3(content)) ##user system elapsed ## 4.422 0.091 4.787 grid.newpage() system.time(table4(content2)) ##user system elapsed ## 8.810 0.184 9.555 2009/9/25 hadley wickham h.wick...@gmail.com: This matches my experience with ggplot2 - I have been gradually moving away from frameGrob and packGrob because doing the placement myself is much faster (and for most of the cases I'm interested in, the full power of packGrob is not needed) Hadley -- http://had.co.nz/ -- Dr Paul Murrell Department of Statistics The University of Auckland Private Bag 92019 Auckland New Zealand 64 9 3737599 x85392 p...@stat.auckland.ac.nz http://www.stat.auckland.ac.nz/~paul/ __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] packGrob and dynamic resizing
Hi, I just tried a fourth variant, closer to what ggplot2 uses (I think): to each grob is assigned a viewport with row and column positions (in my example during their construction, with ggplot2 upon editing), and they're all plotted in a given grid.layout. The timing is poor compared to pushing and upping viewports (twice as long). Why would that be? All the best, baptiste (the full, self-contained comparison file is attached, run as: R --vanilla -f comparison.r ) # below is version 4 only makeContentInVp - function(d){ content - as.character(unlist(c(d))) nc - ncol(d) nr - nrow(d) n2nm - function(nr, nc){ expand.grid(seq(1, nr), seq(1, nc)) } vp.ind - n2nm(nr, nc) textii - function(d, gp=gpar(), name=content-label-){ function(ii) textGrob(label=d[ii], gp=gp, name=paste(name, ii, sep=), vp=viewport(layout.pos.row=vp.ind[ii, 1], layout.pos.col=vp.ind[ii, 2])) } makeOneLabel - textii(d=content, gp=gpar(col=blue)) lg - lapply(seq_along(content), makeOneLabel) list(lg=lg, nrow=nrow(d), ncol=ncol(d)) } ## table4 uses grobs that already have a viewport assigned table4 - function(content){ padding - unit(4, mm) lg - content$lg ## retrieve the widths and heights of all textGrobs wg - lapply(lg, grobWidth) # list of grob widths hg - lapply(lg, grobHeight) # list of grob heights ## concatenate this units widths.all - do.call(unit.c, wg) # all grob widths heights.all - do.call(unit.c, hg)#all grob heights ## matrix-like operations on units to define the table layout widths - colMax.units(widths.all, content$ncol) # all column widths heights - rowMax.units(heights.all, content$nrow) # all row heights vp - viewport(layout=grid.layout(content$nrow,content$ncol, w=widths+padding, h=heights+padding)) grid.draw(gTree(children=do.call(gList, lg), vp=vp)) } # uncomment for timing d - head(iris) #d - iris content2 - makeContentInVp(d) # grid.newpage() # system.time(table3(content)) ##user system elapsed ## 4.422 0.091 4.787 grid.newpage() system.time(table4(content2)) ##user system elapsed ## 8.810 0.184 9.555 2009/9/25 hadley wickham h.wick...@gmail.com: This matches my experience with ggplot2 - I have been gradually moving away from frameGrob and packGrob because doing the placement myself is much faster (and for most of the cases I'm interested in, the full power of packGrob is not needed) Hadley -- http://had.co.nz/ __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] packGrob and dynamic resizing
Thank you Paul, I was convinced I tried this option but I obviously didn't! In ?packGrob, the user is warned that packing grobs can be slow. In order to quantify this, I made the following comparison of 3 functions, - table1 uses frameGrob and packGrob - table2 uses frameGrob but calculates the sizes manually and uses placeGrob - table3 creates a grid.layout and draws the grobs in the different viewports. The three functions have (almost) the same output, but the timing does differ quite substantially ! system.time(table1(content)) # user system elapsed # 126.733 2.414 135.450 system.time(table2(content)) # user system elapsed # 22.387 0.508 24.457 system.time(table3(content)) # user system elapsed # 4.868 0.124 5.695 A few questions: - why should the placeGrob approach of table2 be 5 times slower than table3 (pushing viewports) ? - if so, what are the merits of using a frameGrob over creating a layout manually? - can one add some padding to the content placed with a placeGrob approach? Best regards, baptiste The code follows below, sessionInfo() R version 2.9.2 (2009-08-24) i386-apple-darwin8.11.1 locale: en_GB.UTF-8/en_GB.UTF-8/C/C/en_GB.UTF-8/en_GB.UTF-8 attached base packages: [1] stats graphics grDevices utils datasets grid methods [8] base ### code starts ### library(grid) # a few helping functions rowMax.units - function(u, nrow){ # rowMax with a fake matrix of units matrix.indices - matrix(seq_along(u), nrow=nrow) do.call(unit.c, lapply(seq(1, nrow), function(ii) { max(u[matrix.indices[ii, ]]) })) } colMax.units - function(u, ncol){ # colMax with a fake matrix of units matrix.indices - matrix(seq_along(u), ncol=ncol) do.call(unit.c, lapply(seq(1, ncol), function(ii) { max(u[matrix.indices[, ii]]) })) } textii - function(d, gp=gpar(), name=row-label-){ function(ii) textGrob(label=d[ii], gp=gp, name=paste(name, ii, sep=)) } # create a list of text grobs from a data.frame makeContent - function(d){ content - as.character(unlist(c(d))) makeOneLabel - textii(d=content, gp=gpar(col=blue), name=content-label-) lg - lapply(seq_along(content), makeOneLabel) list(lg=lg, nrow=nrow(d), ncol=ncol(d)) } the comparison starts here ## table1 uses grid.pack table1 - function(content){ gcells = frameGrob(name=table.cells, layout = grid.layout(content$nrow, content$ncol)) label.ind - 1 # index running accross labels for (ii in seq(1, content$ncol, 1)) { for (jj in seq(1, content$nrow, 1)) { gcells = packGrob(gcells, content$lg[[label.ind]], row=jj, col=ii, dynamic=TRUE) label.ind - label.ind + 1 } } grid.draw(gTree(children=gList(gcells))) } ## table2 uses grid.place table2 - function(content){ padding - unit(4, mm) lg - content$lg ## retrieve the widths and heights of all textGrobs (including some zeroGrobs) wg - lapply(lg, grobWidth) # list of grob widths hg - lapply(lg, grobHeight) # list of grob heights ## concatenate this units widths.all - do.call(unit.c, wg) # all grob widths heights.all - do.call(unit.c, hg)#all grob heights ## matrix-like operations on units to define the table layout widths - colMax.units(widths.all, content$ncol) # all column widths heights - rowMax.units(heights.all, content$nrow) # all row heights gcells = frameGrob(name=table.cells, layout = grid.layout(content$nrow, content$ncol, width=widths+padding, height=heights+padding)) label.ind - 1 # index running accross labels for (ii in seq(1, content$ncol, 1)) { for (jj in seq(1, content$nrow, 1)) { gcells = placeGrob(gcells, content$lg[[label.ind]], row=jj, col=ii) label.ind - label.ind + 1 } } grid.draw(gTree(children=gList(gcells))) } ## table3 uses grid.layout table3 - function(content){ padding - unit(4, mm) lg - content$lg ## retrieve the widths and heights of all textGrobs (including some zeroGrobs) wg - lapply(lg, grobWidth) # list of grob widths hg - lapply(lg, grobHeight) # list of grob heights ## concatenate this units widths.all - do.call(unit.c, wg) # all grob widths heights.all - do.call(unit.c, hg)#all grob heights ## matrix-like operations on units to define the table layout widths - colMax.units(widths.all, content$ncol) # all column widths heights - rowMax.units(heights.all, content$nrow) # all row heights cells = viewport(name=table.cells, layout = grid.layout(content$nrow, content$ncol, width=widths+padding, height=heights+padding) ) pushViewport(cells) label.ind - 1 # index running accross labels ## loop over columns and rows for (ii in seq(1, content$ncol, 1)) { for (jj in seq(1, content$nrow, 1)) { ##
Re: [R] packGrob and dynamic resizing
On Fri, Sep 25, 2009 at 7:55 AM, baptiste auguie baptiste.aug...@googlemail.com wrote: Thank you Paul, I was convinced I tried this option but I obviously didn't! In ?packGrob, the user is warned that packing grobs can be slow. In order to quantify this, I made the following comparison of 3 functions, - table1 uses frameGrob and packGrob - table2 uses frameGrob but calculates the sizes manually and uses placeGrob - table3 creates a grid.layout and draws the grobs in the different viewports. The three functions have (almost) the same output, but the timing does differ quite substantially ! This matches my experience with ggplot2 - I have been gradually moving away from frameGrob and packGrob because doing the placement myself is much faster (and for most of the cases I'm interested in, the full power of packGrob is not needed) Hadley -- http://had.co.nz/ __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] packGrob and dynamic resizing
Hi baptiste auguie wrote: Dear all, I'm trying to follow an old document to use Grid frames, Creating Tables of Text Using grid Paul Murrell July 9, 2003 As a minimal example, I wrote this, gf - grid.frame(layout = grid.layout(1, 1), draw = TRUE) label1 - textGrob(test, x = 0, just = left, name=test) gf=placeGrob(gf, rectGrob(), row = 1, col = 1) gf=packGrob(gf, label1, row = 1, col = 1) You need 'dynamic=TRUE' in the call to packGrob() if you want the automatic updating. Paul grid.draw(gf) grid.edit(test, label = longer text, grep=T) I'm a bit lost here, as I was expecting the frame to be automatically adjusted to fit the new text. Can anyone point me in the right direction? Best regards, baptiste __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. -- Dr Paul Murrell Department of Statistics The University of Auckland Private Bag 92019 Auckland New Zealand 64 9 3737599 x85392 p...@stat.auckland.ac.nz http://www.stat.auckland.ac.nz/~paul/ __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
[R] packGrob and dynamic resizing
Dear all, I'm trying to follow an old document to use Grid frames, Creating Tables of Text Using grid Paul Murrell July 9, 2003 As a minimal example, I wrote this, gf - grid.frame(layout = grid.layout(1, 1), draw = TRUE) label1 - textGrob(test, x = 0, just = left, name=test) gf=placeGrob(gf, rectGrob(), row = 1, col = 1) gf=packGrob(gf, label1, row = 1, col = 1) grid.draw(gf) grid.edit(test, label = longer text, grep=T) I'm a bit lost here, as I was expecting the frame to be automatically adjusted to fit the new text. Can anyone point me in the right direction? Best regards, baptiste __ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.