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') ))
Related
I want to use a very small font to fit a lot of records on a gridExtra table, however, I can't find the way to adjust the row heights and widths. Is rowhead = list(bg_params=list(height = unit(1, "npc") the correct argument for row heights?
library(gridExtra)
library(grid)
myt <- ttheme_default(
core = list(fg_params=list(col="blue",fontsize=7),
bg_params=list(col="red",fill=c("azure2","azure"))),
#bg_params=list(fill=c("yellow", "pink"))),
colhead = list(fg_params=list(col="white"),
bg_params=list(fill="red")),
rowhead = list(bg_params=list(height = unit(1, "npc") - unit(2, "scaledpts"))))
dat <- mtcars[1:5,1:5]
dat$mpg <- dat$mpg*1000
grid.newpage()
grid.draw(tableGrob(format(dat, big.mark=","), theme=myt, rows=NULL))
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()
I'm trying to write a function wherein our company logo is automatically added to each graph on export as part of a function, next to the title and subtitle. The dimensions of each output will depend on the needs at the time, so having a set size won't be particularly helpful unfortunately.
To do this, I've generated a series of grids to slot everything together, as per the below (using the iris dataset).
library(datasets)
library(tidyverse)
library(gridExtra)
library(grid)
library(png)
m <- readPNG("Rlogo.png") # download from: https://www.r-project.org/logo/Rlogo.png
plot <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) +
geom_col() +
ggtitle("Title goes here",
subtitle = "subtitle down here")
txtTitle <- plot$labels$title
txtSubTitle <- plot$labels$subtitle
plot$labels$title <- NULL
plot$labels$subtitle <- NULL
buffer <- grobTree(rectGrob(gp = gpar(fill = "white", col = "white")))
Title <- grobTree(textGrob(label = txtTitle,
hjust = 1,
x = 0.98))
SubTitle <- textGrob(label = txtSubTitle,
hjust = 1,
x = 0.98)
Logo <- grobTree(rasterGrob(m, x = 0.02, hjust = 0))
TitlesGrid <- grid.arrange(Title, SubTitle, ncol = 1)
TopGrid <- grid.arrange(Logo, TitlesGrid, widths = c(1, 7), ncol = 2)
AllGrid <- grid.arrange(TopGrid, arrangeGrob(plot), heights = c(1,7))
This provides the following outputs at different aspect ratios.
The first example has a nice gap between the title and subtitle whereas there is too much for the second one. How would I make it so that the height of TopGrid is fixed to an absolute size, but the rest fills to the size desired?
Grid graphics has the concept of absolute and relative units. Absolute units (such as "cm", "in", "pt") always stay the same size, regardless of the viewport size. Relative units (called "null") expand or shrink as needed. In a regular ggplot2 object, the plot panel is specified in relative units while the various elements around the panel, such as title, axis ticks, etc. are specified in absolute units.
You specify absolute or relative units with the unit() function:
> library(grid)
> unit(1, "cm")
[1] 1cm
> unit(1, "null")
[1] 1null
In your case, the heights argument of grid.arrange can take arbitrary grid unit objects, so you just have to give the top height an absolute unit:
grid.arrange(TopGrid, arrangeGrob(plot), heights = unit(c(1, 1), c("cm", "null")))
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') ))
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)