Steen Harsted
Steen Harsted

Reputation: 1932

Plotting tables in facets using ggplot2

I am looking for a way to plot some table data in facets using ggplot2.

Below are sample data and some code that sort of produces a plot of what I am looking for. However, using geom_text() makes it difficult to align the lines, and I have problems with text being cropped when I combine the facetted table-plot with other plots.

Thanks in advance

Libray and sample data text_data

library(tidyverse)

text_data <- data.frame(
  rep = 1:5,
  time = rnorm(5, 2, 0.2),
  x = sample(100:130, 5),
  y = sample(40:50, 5),
  z = rnorm(5, -1, 0.3)
)


# Text data in wide format
text_data
#>   rep     time   x  y         z
#> 1   1 2.192189 129 47 -1.308432
#> 2   2 2.161335 105 46 -1.186042
#> 3   3 2.340631 106 48 -1.270763
#> 4   4 2.136504 124 44 -1.332719
#> 5   5 2.148028 108 42 -1.249902

Text data in the table format I would like to plot, each rep should be a facet

text_data %>%
  pivot_longer(cols = -rep) %>%
  knitr::kable(digits = 1)
rep name value
1 time 2.2
1 x 129.0
1 y 47.0
1 z -1.3
2 time 2.2
2 x 105.0
2 y 46.0
2 z -1.2
3 time 2.3
3 x 106.0
3 y 48.0
3 z -1.3
4 time 2.1
4 x 124.0
4 y 44.0
4 z -1.3
5 time 2.1
5 x 108.0
5 y 42.0
5 z -1.2

Some NOT OPTIMAL to code that produces a facetted plot to show kind of what I am looking for

ggplot(data = text_data) +
  geom_text(
    y = 0.9,
    x = 0.5,
    aes(label = paste("Time:", round(time, 1), "seconds"))
  ) +
  geom_text(
    y = 0.7,
    x = 0.5,
    aes(label = paste("X: ", x))
  ) +
  geom_text(
    y = 0.5,
    x = 0.5,
    aes(label = paste("y: ", y))
  ) +
  geom_text(
    y = 0.3,
    x = 0.5,
    aes(label = paste("z: ", round(z, 1)))
  ) +
  facet_grid(rows = vars(rep)) +
  theme_minimal()

Created on 2022-09-26 by the reprex package (v2.0.1)

Upvotes: 1

Views: 569

Answers (2)

Martin C. Arnold
Martin C. Arnold

Reputation: 9668

Here's an approach using the gridExtra package.

library(tidyverse)
library(gridExtra)

text_data <- data.frame(
  time = rnorm(5, 2, 0.2) ,
  x = sample(100:130, 5),
  y = sample(40:50, 5),
  z = rnorm(5, -1, 0.3)
) %>% 
  mutate(
    across(.f = ~ as.character(round(., 2))),
    time = paste(time, "seconds")
    )
  
grob_list <- map(1:nrow(text_data), ~ {
  text_data[.x,] %>% 
    as_vector() %>% 
    as.matrix(ncol = 1) %>% 
    tableGrob(theme = ttheme_minimal())
})

grid.arrange(grobs = grob_list, ncol = 1)

enter image description here

Upvotes: 2

St&#233;phane Laurent
St&#233;phane Laurent

Reputation: 84599

With ggpp::geom_table:

library(ggplot2)
library(ggpp)
library(dplyr)
library(tidyr)
library(tibble)

text_data <- data.frame(
  rep = 1:5,
  time = rnorm(5, 2, 0.2),
  x = sample(100:130, 5),
  y = sample(40:50, 5),
  z = rnorm(5, -1, 0.3)
) 

dat <- text_data %>% 
  pivot_longer(cols = -rep)
tbs <- lapply(split(dat, dat$rep), "[", -1L)
df <- tibble(x   = rep(-Inf, length(tbs)), 
             y   = rep(Inf, length(tbs)), 
             rep = levels(as.factor(dat$rep)), 
             tbl = tbs)

ggplot(text_data) + 
  geom_point(aes(x = x, y = y)) +
  geom_table(data = df, aes(x = x, y = y, label = tbl),
                hjust = 0, vjust = 1) + 
  facet_wrap(~ rep)

enter image description here

Upvotes: 2

Related Questions