Adding a subtitle text to a grid.table plot - r

I have a question very similar to what discussed here:
Adding text to a grid.table plot
my ultimate goal however is to have a title 60mm from the top of the table, and a subtitle 2mm below the title.
I came up with this code that is almost there but not there, meaning, the subtitle is 2mm from the top of the table, and 2mm below the title, as expected.
library(gridExtra)
library(grid)
library(gtable)
d <- head(iris)
table <- tableGrob(d)
title <- textGrob("Title",gp=gpar(fontsize=50))
subtitle <- textGrob("subtitle", x=0, hjust=0,
gp=gpar( fontface="italic"))
padding <- unit(2,"mm")
table <- gtable_add_rows(table,
heights = grobHeight(subtitle)+ padding,
pos = 0)
padding <- unit(60,"mm")
table <- gtable_add_rows(table,
heights = grobHeight(title) + padding,
pos = 0)
table <- gtable_add_grob(table, list(title, subtitle),
t=c(1, 2), l=c(1,1),
r=ncol(table))
png('tmp.png', width = 480, height = 480, bg = "#FFECDB")
grid.newpage()
grid.draw(table)
dev.off()
I wonder if anybody has a suggestion on how to fix it.
Thank you

I'm new to grid tables, but it appears the order of your grobs matters, at least for padding. Is this the result you are expecting?
library(gridExtra)
library(grid)
library(gtable)
d <- head(iris)
table <- tableGrob(d)
title <- textGrob("Title", gp = gpar(fontsize=50))
subtitle <- textGrob("subtitle", x=0, hjust=0, gp=gpar( fontface="italic"))
table <- gtable_add_rows(table, heights = grobHeight(subtitle) + unit(58,"mm"), pos = 0)
table <- gtable_add_rows(table, heights = grobHeight(title) - unit(60,"mm"), pos = 0)
table <- gtable_add_grob(table, list(title, subtitle), t=c(1,2), l=c(1,1), r=ncol(table))
png('tmp.png', width = 480, height = 480, bg = "#FFECDB")
grid.newpage()
grid.draw(table)
dev.off()

Related

Remove white space of textGrob from grid.arrange

I'm new to grobbing and I am trying to create a simple grid.arrange object but cannot figure out how to might a compact/tight layout.
Below is a simple example of what I'm trying to run and the grob that I get.
library(grid)
library(gridExtra)
name = textGrob("My Name", gp=gpar(fontsize = 20, fontface = "bold"))
name2 = textGrob("Second Name", gp=gpar(fontsize = 16))
tbl = tableGrob(head(iris))
grid.arrange(name, name2, tbl)
UPDATE:
Using the answer found here I was able to get the text compact but I am still struggling to get the table to be right under the text.
library(grid)
library(gridExtra)
name = textGrob("My Name", gp=gpar(fontsize = 20, fontface = "bold"))
name2 = textGrob("Second Name", gp=gpar(fontsize = 16))
tbl = tableGrob(head(iris))
margin = unit(0.5, "line")
grid.newpage()
grid.arrange(name, name2, tbl,
heights = unit.c(grobHeight(name) + 1.2*margin,
grobHeight(name2) + margin,
unit(1,"null")))
Typically you'd use the top= argument for a single grob. With two grobs like this, it might be easiest to combine them in a table; the major hurdle is that gtable doesn't consider justification so you have to adjust the positions yourself,
library(gtable)
justify <- function(x, hjust="center", vjust="top", draw=FALSE){
w <- sum(x$widths)
h <- sum(x$heights)
xj <- switch(hjust,
center = 0.5,
left = 0.5*w,
right=unit(1,"npc") - 0.5*w)
yj <- switch(vjust,
center = 0.5,
bottom = 0.5*h,
top=unit(1,"npc") - 0.5*h)
x$vp <- viewport(x=xj, y=yj)
if(draw) grid.draw(x)
return(x)
}
title <- gtable_col('title', grobs = list(name,name2),
heights = unit.c(grobHeight(name) + 1.2*margin,
grobHeight(name2) + margin))
grid.newpage()
grid.arrange(justify(title, vjust='bottom'), justify(tbl))

Decrease size of table in gridExtra::tableGrob [duplicate]

I have a fairly wide table (4/3 of page width) that I'm trying to print using grid.table or grid.arrange (via tableGrob) into a pdf file. The table goes beyond page boundaries and gets clipped. Is there a way to force grid.table/grid.arrange to scale the table to the print area?
There is a way, but it's unclear what should happen when the text is too wide to fit in some cells.
One option is to set the widths manually,
library(grid)
library(gridExtra)
g1 <- g2 <- tableGrob(head(iris, 10), rows=NULL)
g2$widths <- unit(rep(1/ncol(g2), ncol(g2)), "npc")
grid.newpage()
gt = arrangeGrob(textGrob("page 1"), textGrob("page 2"),
rectGrob(gp=gpar(fill="grey98")),
rectGrob(gp=gpar(fill="grey98")),
nullGrob(),
layout_matrix=rbind(c(1,5,2), c(3,5,4)),
widths = unit(c(1,5,1),c("null", "cm", "null")),
heights = unit(c(1, 1),c("line", "null")),
vp = viewport(width=0.9, height=0.9))
tc = list(g1, g2)
gt <- gtable::gtable_add_grob(gt, tc, l=c(1,3), t=2,
name="newgrobs")
grid.draw(gt)
but of course with a fixed font size it means that some text might be cut.
Probably a better option is to introduce line breaks, and/or (slightly) reduce the font size.
g3 <- tableGrob(head(iris, 10), theme = ttheme_default(7),
rows=NULL, cols=gsub("\\.", "\\\n",names(iris)))
g3$widths <- unit(rep(1/ncol(g2), ncol(g2)), "npc")
grid.newpage()
gt = arrangeGrob(textGrob("page 1"), textGrob("page 2"),
rectGrob(gp=gpar(fill="grey98")),
rectGrob(gp=gpar(fill="grey98")),
nullGrob(),
layout_matrix=rbind(c(1,5,2), c(3,5,4)),
widths = unit(c(1,1,1),c("null", "line", "null")),
heights = unit(c(1, 1),c("line", "null")),
vp = viewport(width=0.9, height=0.9))
tc = list(g2, g3)
gt <- gtable::gtable_add_grob(gt, tc, l=c(1,3), t=2,
name="newgrobs")
grid.draw(gt)
I got this done using font sizes. Not the best solution (requires manual intervention) but maybe someone can contribute something more elegant.
termTable = tableGrob(terms, h.even.alpha=1, h.odd.alpha=1, v.even.alpha=0.5, v.odd.alpha=1, core.just='left', rows=c(),
gpar.coretext =gpar(fontsize=8),
gpar.coltext=gpar(fontsize=10, fontface='bold'),
gpar.rowtext=gpar(fontsize=10, fontface='bold')
)
With the most recent version of gridExtra, the correct formatting to update rimorob's answer is:
termTable = tableGrob(terms, theme =ttheme_default(gpar.coretext =gpar(fontsize=8), gpar.coltext=gpar(fontsize=10, fontface='bold'), gpar.rowtext=gpar(fontsize=10, fontface='bold') ))

How can I add a title to a tableGrob plot?

I have a table, and I want to print a title above it:
t1 <- tableGrob(top_10_events_by_casualties, cols=c("EVTYPE", "casualties"), rows=seq(1,10))
grid.draw(t1)
A similar question was asked here: Adding text to a grid.table plot
I've tried something similar and it doesn't work:
> title <- textGrob("Title",gp=gpar(fontsize=50))
> table <- gtable_add_rows(t1,
+ heights = grobHeight(title) + padding,
+ pos = 0)
Error: is.gtable(x) is not TRUE
Not sure what the problem was, but here is a working example:
library(grid)
library(gridExtra)
library(gtable)
t1 <- tableGrob(head(iris))
title <- textGrob("Title",gp=gpar(fontsize=50))
padding <- unit(5,"mm")
table <- gtable_add_rows(
t1,
heights = grobHeight(title) + padding,
pos = 0)
table <- gtable_add_grob(
table,
title,
1, 1, 1, ncol(table))
grid.newpage()
grid.draw(table)
Another option is:
library(gridExtra)
grid.arrange(top="Iris dataset", tableGrob(head(iris)))
You still might want to do some tweaking with the padding.

R save table as image

I would like to export a data frame as a (png) image. I've tried with this code, but the table get clipped vertically.
library(ggplot2)
library(gridExtra)
df <- data.frame(a=1:30, b=1:30)
png("test.png")
p<-tableGrob(df)
grid.arrange(p)
dev.off()
Is there a way to avoid this behaviour without having to set manually the size of the image?
You can change this behavior by specifying a height and width.
png("test.png", height=1000, width=200)
p<-tableGrob(df)
grid.arrange(p)
dev.off()
Anyway, it is usually not very helpful to save tables as pictures.
You can do like this:
library(gridExtra)
png("test.png", height = 50*nrow(df), width = 200*ncol(df))
grid.table(df)
dev.off()
This works just fine:
library(gridExtra)
df = data.frame("variables" = c("d_agr","d_def","d_frig","d_hidro","d_roads","d_silos"),
"coeficient" = c(0.18,0.19,-0.01,-0.25,-0.17,0.09))
png("output.png", width=480,height=480,bg = "white")
grid.table(df)
dev.off()
To get the size of the table you have to generate a tableGrob first, than you can get the height and width parameters. The parameters are "grobwidth", they have to be converted into inch.
Here is my solution (base on gridExtra vignettes), it works fine for me.
library(grid)
library(gridExtra)
gridFtable <- function(d, pd = 4, fontsize = 10, fontfamily = "PT Mono") {
## set plot theme
t1 <- ttheme_default(padding = unit(c(pd, pd), "mm"), base_size = fontsize, base_family = fontfamily)
## character table with added row and column names
extended_matrix <- cbind(c("", rownames(d)), rbind(colnames(d), as.matrix(d)))
## get grob values
g <- tableGrob(extended_matrix, theme = t1)
## convert widths from grobwidth to inch
widthsIn <- lapply(g$widths, function(x) {convertUnit(x, unitTo = "inch", valueOnly = TRUE)})
heigthsIn <- lapply(g$heights, function(x) {convertUnit(x, unitTo = "inch", valueOnly = TRUE)})
## calculate width and height of the table
w <- sum(unlist(widthsIn)) - 1*convertUnit(unit(pd, "mm"), unitTo = "inch", valueOnly = TRUE)
h <- sum(unlist(heigthsIn)) - 1*convertUnit(unit(pd, "mm"), unitTo = "inch", valueOnly = TRUE)
return(list(grobData = g, data = d, width = w, heigth = h, theme = t1))
}
saveTable <- gridFtable(data.frame(a=1:30, b=1:30))
png(file = "./test.png", width = saveTable$width, height = saveTable$heigth, units = "in", res = 100)
grid.newpage()
grid.table(saveTable$data, rows = NULL, theme = saveTable$theme)
dev.off()
getwd()

Adding text to a grid.table plot

I have recently started using the grid.table function from the gridExtra package to turn tabular data into png image files for use on the web. I've been delighted with it so far as it produces very good-looking output by default, sort of like a ggplot2 for tables. Like the person who asked this question I would love to see the ability to specify the justification for individual columns but that would be icing on what is an already more-ish cake.
My question is whether it is possible to add text around a grid.table so that I can give plotted tables a title and a footnote. It seems to me this should be feasible, but I don't know enough about grid graphics to be able to work out how to add grobs to the table grob. For example, this code:
require(gridExtra)
mydf <- data.frame(Item = c('Item 1','Item 2','Item 3'),
                    Value = c(10,15,20), check.names = FALSE)
grid.table(mydf,
gpar.coretext=gpar(fontsize = 16),
gpar.coltext = gpar(fontsize = 16),
gpar.rowtext = gpar(fontsize = 16),
gpar.corefill = gpar(fill = "blue", alpha = 0.5, col = NA),
h.even.alpha = 0.5,
equal.width = FALSE,
show.rownames = FALSE,
show.vlines = TRUE,
padding.h = unit(15, "mm"),
padding.v = unit(8, "mm")
)
generates this plot:
when I would really like to be able to do something like the following in code rather than by editing the image with another application:
To place text close to the table you'll want to evaluate the table size first,
library(gridExtra)
d <- head(iris)
table <- tableGrob(d)
grid.newpage()
h <- grobHeight(table)
w <- grobWidth(table)
title <- textGrob("Title", y=unit(0.5,"npc") + 0.5*h,
vjust=0, gp=gpar(fontsize=20))
footnote <- textGrob("footnote",
x=unit(0.5,"npc") - 0.5*w,
y=unit(0.5,"npc") - 0.5*h,
vjust=1, hjust=0,gp=gpar( fontface="italic"))
gt <- gTree(children=gList(table, title, footnote))
grid.draw(gt)
Edit (17/07/2015) With gridExtra >=2.0.0, this approach is no longer suitable. tableGrob now returns a gtable, which can be more easily customised.
library(gridExtra)
d <- head(iris)
table <- tableGrob(d)
library(grid)
library(gtable)
title <- textGrob("Title",gp=gpar(fontsize=50))
footnote <- textGrob("footnote", x=0, hjust=0,
gp=gpar( fontface="italic"))
padding <- unit(0.5,"line")
table <- gtable_add_rows(table,
heights = grobHeight(title) + padding,
pos = 0)
table <- gtable_add_rows(table,
heights = grobHeight(footnote)+ padding)
table <- gtable_add_grob(table, list(title, footnote),
t=c(1, nrow(table)), l=c(1,2),
r=ncol(table))
grid.newpage()
grid.draw(table)
If you want just the title (no footnote), here is a simplified version of #baptiste's example:
title <- textGrob("Title", gp = gpar(fontsize = 50))
padding <- unit(0.5,"line")
table <- gtable_add_rows(
table, heights = grobHeight(title) + padding, pos = 0
)
table <- gtable_add_grob(
table, list(title),
t = 1, l = 1, r = ncol(table)
)
grid.newpage()
grid.draw(table)

Resources