Is there an elegant way to align the tableGrob rows with the axis breaks?
是否有一种优雅的方式来对齐tableGrob行与轴中断?
I would like to juxtapose a tableGrob and ggplot chart in R (I need to reproduce some SAS output used in previous versions of a public report). Like this minimal reproducible example:
我想在R(我需要复制在公共报告的以前版本中使用的一些SAS输出)中使用tableGrob和ggplot图。就像这个最小可重复的例子:
This post got me pretty far --- the tableGrob is in the same gtable row as the body of the chart; however, it requires lots of manual fiddling to get the rows in the tableGrob to line up with the axis labels.
这篇文章让我走得很远——tableGrob和图表的主体是一样的。但是,它需要大量手工操作来获取tableGrob中的行以与axis标签对齐。
I also found this post. Since I'm Sweaving a public report, I would prefer not to use code that isn't readily available in a package on CRAN. That being said, the experimental version of tableGrob appears to accept heights as an argument. If this code will do the trick, and I do choose to use this experimental version, how would I calculate the appropriate row heights?
我也找到了这个帖子。由于我正在做一个公开的报告,所以我宁愿不使用在CRAN上的包中不容易获得的代码。话虽如此,tableGrob的实验版本似乎接受高度作为一个论点。如果这段代码能做到这一点,并且我选择使用这个实验版本,我将如何计算合适的行高度?
If there is not an elegant way of doing this, I found these tricks to be helpful:
如果没有一种优雅的方法来做这件事,我发现这些窍门是有用的:
- set fontsize AND cex in tableGrob to match ggplot2
- 在tableGrob中设置fontsize和cex匹配ggplot2。
- set padding.v to space table rows in tableGrob
- 设置填充。在tableGrob中对空间表行。
- modify coordinate limits to accomodate column labels and align with bottom of last row
- 修改坐标限制,以适应列标签,并与最后一行的底部对齐。
My MRE code:
我的绝笔代码:
library(ggplot2)
library(gridExtra)
library(gtable)
theme_set(theme_bw(base_size = 8))
df <- head(mtcars,10)
df$cars <- row.names(df)
df$cars <- factor(df$cars, levels=df$cars[order(df$disp, decreasing=TRUE)], ordered=TRUE)
p <- ggplot(data=df, aes(x=hp, y=cars)) +
geom_point(aes(x=hp, y=cars)) +
scale_y_discrete(limits=levels(df$cars))+
theme(axis.title.y = element_blank()) +
coord_cartesian(ylim=c(0.5,length(df$cars)+1.5))
t <- tableGrob(df[,c("mpg","cyl","disp","cars")],
cols=c("mpg","cyl","disp","cars"),
gpar.coretext = gpar(fontsize = 8, lineheight = 1, cex = 0.8),
gpar.coltext = gpar(fontsize = 8, lineheight = 1, cex = 0.8),
show.rownames = FALSE,
show.colnames = TRUE,
equal.height = TRUE,
padding.v = unit(1.65, "mm"))
g <- NULL
g <- ggplotGrob(p)
g <- gtable_add_cols(g, unit(2,"in"), 0)
g <- gtable_add_grob(g, t, t=3, b=3, l=1, r=1)
png('./a.png', width = 5, height = 2, units = "in", res = 100)
grid.draw(g)
dev.off()
I have left the car names on the y-axis breaks for troubleshooting purposes, but ultimately I will remove them.
我在y轴上留下了汽车名称,用于故障排除,但最终我将删除它们。
2 个解决方案
#1
5
There's now this experimental version of gtable_table
现在有了gtable_table的实验版本。
table <- gtable_table(df[,c("mpg","cyl","disp","cars")],
heights = unit(rep(1,nrow(df)), "null"))
g <- ggplotGrob(p)
g <- gtable_add_cols(g, sum(table$widths), 0)
g <- gtable_add_grob(g, table, t=3, b=3, l=1, r=1)
grid.newpage()
grid.draw(g)
#2
2
@Baptiste's answer expanded to demonstrate column labels and cell parameters:
@Baptiste的回答扩展到显示列标签和单元格参数:
library(ggplot2)
library(gridExtra)
## I manually changed the dependency on
install.packages(".//gtable_0.2.tar.gz", repos = NULL, type="source")
## The forked version of gtable requires R version 3.2.0
## which is currently in development (as of 9/17/2014) due to change in grid
## (https://github.com/wch/r-source/commit/850a82c30e91feb47a0b6385adcbd82988d90413)
## I have not installed the development version.
## However, I was able, in limited testing, to get this to work with R 3.1.0
## and ggplot2_1.0.0
## YRMV
## The following code, commented out, may be more useful with release of R 3.2.0
## library(devtools)
## devtools::install_github("baptiste/gtable")
library(gtable)
theme_set(theme_bw(base_size = 10))
df <- mtcars
df$cars <- row.names(df)
df <- head(df[,c("mpg","cyl","disp","cars")],10)
df$cars <- factor(df$cars, levels=df$cars[order(df$disp, decreasing=TRUE)], ordered=TRUE)
p <- ggplot(data=df, aes(x=disp, y=cars)) +
geom_point(aes(x=disp, y=cars)) +
scale_y_discrete(limits=levels(df$cars))+
theme(axis.title.y = element_blank()) +
coord_cartesian(ylim = c(0.5,nrow(df)+1))
core <- gtable_table(df[order(df$disp, decreasing=FALSE),],
fg.par = list(fontsize=c(8)),
bg.par = list(fill=c(rep("lightblue",4),rep("white",4)), alpha=0.5),
heights = unit(rep(1,nrow(df)), "null"))
colHead <- gtable_table(t(colnames(df)),
fg.par = list(fontsize=c(8)),
bg.par = list(fill=c(1), alpha=0.2),
heights = unit(0.5, "null"))
table1 <- rbind(colHead, core)
g <- ggplotGrob(p)
g <- gtable_add_cols(g, sum(table1$widths), 0)
g <- gtable_add_grob(g, table1, t=3, b=3, l=1, r=1)
grid.newpage()
grid.draw(g)
#1
5
There's now this experimental version of gtable_table
现在有了gtable_table的实验版本。
table <- gtable_table(df[,c("mpg","cyl","disp","cars")],
heights = unit(rep(1,nrow(df)), "null"))
g <- ggplotGrob(p)
g <- gtable_add_cols(g, sum(table$widths), 0)
g <- gtable_add_grob(g, table, t=3, b=3, l=1, r=1)
grid.newpage()
grid.draw(g)
#2
2
@Baptiste's answer expanded to demonstrate column labels and cell parameters:
@Baptiste的回答扩展到显示列标签和单元格参数:
library(ggplot2)
library(gridExtra)
## I manually changed the dependency on
install.packages(".//gtable_0.2.tar.gz", repos = NULL, type="source")
## The forked version of gtable requires R version 3.2.0
## which is currently in development (as of 9/17/2014) due to change in grid
## (https://github.com/wch/r-source/commit/850a82c30e91feb47a0b6385adcbd82988d90413)
## I have not installed the development version.
## However, I was able, in limited testing, to get this to work with R 3.1.0
## and ggplot2_1.0.0
## YRMV
## The following code, commented out, may be more useful with release of R 3.2.0
## library(devtools)
## devtools::install_github("baptiste/gtable")
library(gtable)
theme_set(theme_bw(base_size = 10))
df <- mtcars
df$cars <- row.names(df)
df <- head(df[,c("mpg","cyl","disp","cars")],10)
df$cars <- factor(df$cars, levels=df$cars[order(df$disp, decreasing=TRUE)], ordered=TRUE)
p <- ggplot(data=df, aes(x=disp, y=cars)) +
geom_point(aes(x=disp, y=cars)) +
scale_y_discrete(limits=levels(df$cars))+
theme(axis.title.y = element_blank()) +
coord_cartesian(ylim = c(0.5,nrow(df)+1))
core <- gtable_table(df[order(df$disp, decreasing=FALSE),],
fg.par = list(fontsize=c(8)),
bg.par = list(fill=c(rep("lightblue",4),rep("white",4)), alpha=0.5),
heights = unit(rep(1,nrow(df)), "null"))
colHead <- gtable_table(t(colnames(df)),
fg.par = list(fontsize=c(8)),
bg.par = list(fill=c(1), alpha=0.2),
heights = unit(0.5, "null"))
table1 <- rbind(colHead, core)
g <- ggplotGrob(p)
g <- gtable_add_cols(g, sum(table1$widths), 0)
g <- gtable_add_grob(g, table1, t=3, b=3, l=1, r=1)
grid.newpage()
grid.draw(g)