问题
I'm having difficulty to find solution for aligning ggplot grob and table grob. I tried to follow the instruction here but still didn't give the results I wanted.
library(grid)
library(gridExtra)
library(ggplot2)
library(tibble)
library(gtable)
dat <- tibble::rownames_to_column(mtcars, "car") #convert rownames to first col
plot1 <- ggplot(dat, aes(car, mpg)) +
geom_bar(stat = "identity") +
coord_flip()
g1 <- ggplotGrob(plot1)
tb1 <- tableGrob(dat$cyl)
g1 <- gtable_add_cols(g1, unit(0.2, "npc"))
g1 <- gtable_add_grob(g1, grobs = tb1, t=3, l=ncol(g1), b=6, r=ncol(g1))
grid.newpage()
grid.draw(g1)
I would like that each cell in the table be aligned to related bar in histogram, but still couldn't understand how the t,l,b,r be implemented from the layout.This is the output I got
回答1:
By default the cell heights have absolute sizes to accommodate the text, but you can change them to relative units so that they scale with the plot panel,
library(grid)
library(gridExtra)
library(ggplot2)
library(tibble)
library(gtable)
dat <- tibble::rownames_to_column(mtcars, "car") #convert rownames to first col
plot1 <- ggplot(dat, aes(car, mpg)) +
geom_bar(stat = "identity") +
coord_flip()
g1 <- ggplotGrob(plot1)
tb1 <- tableGrob(dat$cyl, theme = ttheme_default(10))
tb1$heights = unit(rep(1/(nrow(tb1)), nrow(tb1)), "npc")
tb1$widths = unit.pmax(tb1$widths, unit(2, "lines"))
g1 <- gtable_add_cols(g1, sum(tb1$widths))
g1 <- gtable_add_grob(g1, grobs = tb1, t=6, l=ncol(g1), b=6, r=ncol(g1))
grid.newpage()
grid.draw(g1)
回答2:
I had a similar question as above when trying to make something like a forestplot in R using ggplot2 and didn't find any of the other solutions fit my needs. The answer above didn't work for me - the table didn't show up. So I hacked together a codewise not that pretty solution, but I actually kind of like the cleanliness visual output.
The things I like about this solution are:
- I aligned a set of custom text not in a table, but just in a figure on the right, where the alignment matched for each text entry and each label in the figure.
- I used a centered ggtitle to align a "column heading" above each set of text. These could be strings of any kind (in my actual use, I had point estimates and confidence intervals).
library(gridExtra)
library(ggplot2)
dat <- data.frame(
label = c("A", "B", "C"),
point_est = c(1,2,3),
lb_ci = c(.5, 1.5, 2.5),
ub_ci = c(1.5, 2.5, 3.5),
n = c(50, 100, 150),
total = c(75, 150, 200)
)
plot1 <- ggplot(dat, aes(x=point_est, y=label)) +
geom_point() +
geom_errorbarh(aes(xmin=lb_ci, xmax=ub_ci), height=.5) +
ggtitle("Some measure") +
ylab(NULL) + xlab("some effect estimate")
tab_base <- ggplot(dat, aes(y=label)) +
ylab(NULL) + xlab(" ") +
theme(plot.title = element_text(hjust = 0.5, size=12), ## centering title on text
axis.text.x=element_text(color="white"), ## need text to be printed so it stays aligned with figure but white so it's invisible
axis.line=element_blank(),
axis.text.y=element_blank(),axis.ticks=element_blank(),
axis.title.y=element_blank(),legend.position="none",
panel.background=element_blank(),panel.border=element_blank(),panel.grid.major=element_blank(),
panel.grid.minor=element_blank(),plot.background=element_blank())
tab1 <- tab_base +
geom_text(aes(x=1, label=n)) +
ggtitle("n")
tab2 <- tab_base +
geom_text(aes(x=1, label=total)) +
ggtitle("total")
lay <- matrix(c(1,1,1,1,1,1,2,3), nrow=1)
grid.arrange(plot1, tab1, tab2, layout_matrix = lay)
来源:https://stackoverflow.com/questions/40265494/ggplot-grobs-align-with-tablegrob