How to Add a Table to My Ggplot2 Output

How can I add a table to my ggplot2 output?

Here's a basic example of the strategy used by learnr:

require(ggplot2)
df <- data.frame(a = seq(0, 90, 10), b = seq(10, 100, 10))
df.plot <- ggplot(data = df, aes(x = seq(1, 100, 10))) +
geom_line(aes(y = a), colour = 'red') +
geom_line(aes(y = b), colour = 'blue') +
scale_x_continuous(breaks = seq(0,100,10))

# make dummy labels for the table content
df$lab <- month.abb[ceiling((df$a+1)/10)]

df.table <- ggplot(df, aes(x = a, y = 0,
label = lab, colour = b)) +
geom_text(size = 3.5) +
theme_minimal() +
scale_y_continuous(breaks=NULL)+
theme(panel.grid.major = element_blank(), legend.position = "none",
panel.border = element_blank(), axis.text.x = element_blank(),
axis.ticks = element_blank(),
axis.title.x=element_blank(),
axis.title.y=element_blank())

gA <- ggplotGrob(df.plot)
gB <- ggplotGrob(df.table)[6,]
gB$heights <- unit(1,"line")


require(gridExtra)
gAB <- rbind(gA, gB)
grid.newpage()
grid.draw(gAB)

Sample Image

How to add a table to a ggplot?

You can use fonction flextable::as_raster to get a raster from a flextable and then add with annotation_custom to an empty ggplot object.

library(ggplot2)
library(flextable)
library(grid)
library(cowplot)
library(tidyverse)

mydf <- tibble(a = c(1,2,3,4,5,4),
b = c(4,4,4,3,3,3))

p1 <- mydf %>% ggplot(aes(x = a, y = b, color = as.factor(b))) + geom_point()

ft_raster <- mydf %>% flextable::flextable() %>%
as_raster()

p2 <- ggplot() +
theme_void() +
annotation_custom(rasterGrob(ft_raster), xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf)

cowplot::plot_grid(p1, p2, nrow = 2, ncol = 1, rel_heights = c(4, 1) )

Sample Image

Documentation is here: https://davidgohel.github.io/flextable/articles/offcran/images.html

Adding table within the plotting region of a ggplot in r

You can use ggplot2's annotation_custom with a tableGrob from the gridExtra package.

library(ggplot2)
library(gridExtra)
set.seed(1)
mydata <- data.frame(a=1:50, b=rnorm(50))
mytable <- cbind(sites=c("site 1","site 2","site 3","site 4"),mydata[10:13,])
k <- ggplot(mydata,aes(x=a,y=b)) +
geom_point(colour="blue") +
geom_point(data=mydata[10:13, ], aes(x=a, y=b), colour="red", size=5) +
annotation_custom(tableGrob(mytable), xmin=35, xmax=50, ymin=-2.5, ymax=-1)

Sample Image

how to insert gt table into a ggplot2 line chart

I was able to find a solution to this problem by using the patchwork package

the name of my table I want to insert is called my_table

my plot is p

library (patchwork)
wrap_plots(p,my_table)

which in return gives me the solution to the problem

summary table with chart in output

Sample Image

I can't seems to reproduce your example, but I understand you want to combine a table and a plot. I used some hypothetical data as example.

You can create the table as grob object using tableGrob function from gridExtra package, convert the ggplot to a grob object using ggplotGrob from ggplot2 package, and then combine them in different ways.

  1. annotation_custom function from ggplot2 package: Here you can feck an empty ggplot and arrange the table and the plot in different regions of the empty plot (see code example below)
# making the plot 
plot_df <- data.frame(x=LETTERS[1:5], y=1:5)
plot <- ggplot(plot_df, aes(x, y))+
geom_col()

# making the table
table_df <- data.frame(x=LETTERS[1:10], y=1:10)
tabl <- tableGrob(d = table_df)

# making the feck plot that will contain the plot and the table
feck_plot_df <- data.frame(x=0:1, y=0:1)
p <- ggplot(feck_plot_df)+
geom_blank()+
annotation_custom(grob = tabl,
xmin = -Inf, xmax = 0.1, ymin = 0.15, ymax = 0.9)+
annotation_custom(grob = ggplotGrob(plot),
xmin = 0.1, xmax = 1, ymin = -Inf, ymax = 1)

# saving the combined plot
ggsave(plot = p, filename = 'combined_plot.png', device = 'png', dpi = 300,
width = 7.04, height = 3.77)

You can also coerce the flexible table to raster flexible::as_raster, then to grob using grid::rasterGrob and arrange things in an empty ggplot. Based on your updates, below is an attempt to arrange the 3 plots.

tabl <- tab_std(data=df, var = "col1", Name_of_variable = "state")
chrt <- donut(df,"col1")

tabl <- tab_std(data=df, var = "col1", Name_of_variable = "state")
bplt <- single_bar(df,"col1", SORT = TRUE)

ggplot() +
theme_void()+
annotation_custom(grid::rasterGrob(as_raster(tabl)), xmin=-Inf, xmax=0.5, ymin=0.5, ymax=Inf)+
annotation_custom(ggplotGrob(chrt), xmin=-Inf, xmax=0.5, ymin=-Inf, ymax=0.5)+
annotation_custom(ggplotGrob(bplt), xmin=0.5, xmax=Inf, ymin=-Inf, ymax=Inf)

  1. Grid-based layouts functions from gridExtra package: Here, you may want to try grid.arrange, arrangeGrob, or gtable_cbind.
tabl <- tab_std(data=df, var = "col1", Name_of_variable = "state")
chrt <- donut(df,"col1")

tabl <- tab_std(data=df, var = "col1", Name_of_variable = "state")
bplt <- single_bar(df,"col1", SORT = TRUE)


grid.arrange(grid::rasterGrob(as_raster(tabl)), ggplotGrob(chrt), ggplotGrob(bplt),
layout_matrix = cbind(rbind(1,2), rbind(3,3)))

Once you get the plot saved somewhere, then you can just include it into your rmarkdown using include_graphics function from knitr package. You can also directly include it without saving.

Adding a table of values below the graph in ggplot2


tt <- ttheme_default(colhead=list(fg_params = list(parse=TRUE)),
base_size = 10,
padding = unit(c(2, 4), "mm"))
tbl <- tableGrob(df1, rows=NULL, theme=tt)

png("E:/temp/test.png", width = 1000, height = 1000)
grid.arrange(plot1, plot2, tbl,
nrow = 3, heights = c(2, 2, 0.5))
dev.off()

resulting plot

how to create a table

You can plot the table values in a separate plot, as the comments suggested, and arrange the plots using plot_grid from the cowplot package.

library(cowplot)
# assume the original plot was named p1

p2 <- ggplot(df, aes(x=avisit, y=forcats::fct_rev(Type), label = n)) +
geom_text(size = 3) +
xlab("") +
facet_grid(.~factor(visit)) +
theme_void() +
theme(axis.text.y = element_text(size = 10, margin = margin(r = 0)),
panel.spacing = unit(0, "mm"),
strip.text = element_blank())
# vary the size in geom_text / axis.text.y depending on your desired plot dimensions.

plot_grid(p1, p2, align = "v", axis = "lr",
ncol = 1, rel_heights = c(1, 0.2))

plot

How can I add a table to a graph?

It's a bit of a hack, but you can annotate with geom_text, placing the text as a slightly negative y value. This puts it into the plot area rather than below the axis.

ggplot(dat, aes(x=Member, y=Percentage)) + 
geom_bar(stat="identity", position="dodge", fill="white", colour="black") +
geom_text(aes(x=table_total, label=table_values), y=-2, data=tab)

Using geom_text to make something like a table in a graph

I more involved approach would be to create two separate plots, one that is the bar chart, one that is the "table" (turning off almost all the theme elements) and using something like align.plots (not sure if that is the right name) in the ggExtra package.

Is it possible to combine a ggplot legend and table

A simple approach is to use the legend labels themselves as the table. Here I demonstrate using knitr::kable to automatically format the table column widths:

library(knitr)
table = summary.table %>%
rename(`Prb FR` = prob.fr, `Prb ED` = prob.ed.n) %>%
kable %>%
gsub('|', ' ', ., fixed = T) %>%
strsplit('\n') %>%
trimws
header = table[[1]]
header = paste0(header, '\n', paste0(rep('─', nchar(header)), collapse =''))
table = table[-(1:2)]
table = do.call(rbind, table)[,1]
table = data.frame(N=summary.table$N, lab = table)

plot_data = full.data %>%
group_by(N) %>%
do({
tibble(error = seq(min(.$error), max(.$error),length.out=100),
prob.ed.n = pchip(.$error, .$prob.ed.n, error))
}) %>%
left_join(table)

ggplot(plot_data, aes(x = error, y = prob.ed.n, group = N, colour = lab)) +
geom_line() +
guides(color = guide_legend(header, reverse=TRUE,
label.position = "left",
title.theme = element_text(size=8, family='mono'),
label.theme = element_text(size=8, family='mono'))) +
theme(
legend.key = element_rect(fill = NA, colour = NA),
legend.spacing.y = unit(0, "pt"),
legend.key.height = unit(10, "pt"),
legend.background = element_blank())

Sample Image



Related Topics



Leave a reply



Submit