1

I've been trying to plot tables in R (see: Plot a table where specific rows can be highlighted (gridExtra alternative)) and ggplot2 is very close to being able to do it in a sensible manner. The main feature that stops it being easy is that you cannot move the x-axis, so you can't use it as a header.

Instead I have managed the following hack:

Libraries

library(ggplot2)
library(data.table)

Example data:

DT <- data.table(Meal = c("Spam", "Eggs", "Spam\nand Eggs"), Price = c(5.00,4.50, 7.00), Calories = c(200,250,400))
DT <- melt(DT, id = "Meal")
DT <- DT[, highlightCell := (value == min(value)), by = variable]
DT

             Meal value variable highlightCell
1:           Spam   5.0    Price         FALSE
2:           Eggs   4.5    Price          TRUE
3: Spam\nand Eggs   7.0    Price         FALSE
4:           Spam 200.0 Calories          TRUE
5:           Eggs 250.0 Calories         FALSE
6: Spam\nand Eggs 400.0 Calories         FALSE

Table making code:

table_theme <- theme(axis.line=element_blank(),
                     axis.text.x=element_blank(),
                     axis.text.y=element_blank(),
                     axis.ticks=element_blank(),
                     axis.title.x=element_blank(),
                     axis.title.y=element_blank(),
                     panel.background=element_blank(),
                     panel.border=element_blank(),
                     panel.grid.major=element_blank(),
                     panel.grid.minor=element_blank(),
                     plot.background=element_blank())

cellfontsize <- 12
headerfontsize <- 7
headerColour <- "grey"

ggplot(DT, aes(x = variable, y=Meal, label = value, fill = highlightCell, xmin = as.numeric(factor(variable)) - 0.5, xmax = as.numeric(factor(variable)) + 0.5, ymin = as.numeric(factor(Meal)) - 0.5, ymax = as.numeric(factor(Meal)) + 0.5)) + 
  # This does the cells
  geom_rect() + geom_text(size = cellfontsize) +
  # Next four lines do the headers (ugly)
  geom_rect(aes(ymin = length(levels(factor(Meal))) + 0.5, ymax = length(levels(factor(Meal))) + 1.5), fill = headerColour) +
  geom_rect(aes(xmin = -0.5, xmax=0.5), fill = headerColour) +
  geom_text(aes(y = length(levels(factor(Meal))) + 1, label = variable), size = headerfontsize) +
  geom_text(aes(x = 0, label = Meal), size = headerfontsize) +
  table_theme + coord_cartesian(xlim=c(-1,3), ylim=c(-1,5))

Example Table Graph

Ideally:

Ideally to make this look like ggplot, I'd like to wrap up those above lines so that they just pick up on the aesthetics in the ggplot command, but I have no idea how to "access" that information to create a new geom_ type function.

For example, the ideal syntax would probably be something like:

ggplot(DT, aes(x=variable, y=Meal, label=value, fill=highlightCell)) + 
    geom_tablecells() + 
    geom_tablerowheader() + geom_tablecolheader() + theme_table()

Can anyone give any pointers how one wrap the above into new geom functions?

I tried, this but it doesn't work:

geom_tablecells <- function(...) {
    return(geom_test(...) + geom_rect(..., size = cellfontsize))
}
Community
  • 1
  • 1
Corvus
  • 7,548
  • 9
  • 42
  • 68
  • you could study the ggplot [source code](https://github.com/hadley/ggplot2/tree/master/R). it is all open "access." why do you want to create tables in ggplot? – rawr Jul 08 '14 at 14:36
  • @rawr so it comes down to a low level coding tasks - I was hoping there would be a way of "wrapping" the above, without going under the hood of ggplot2. It looks superficially like the cell plotting and the header plotting lines should be wrappable a la my attempt at the end but I can't figure out how. Seems you can't pre-add together geoms. Probably a task a little to advanced for me at this stage. – Corvus Jul 08 '14 at 14:42
  • @rawr as to why tables as plots, I'm using `RStudio/knitr/rmarkdown/beamer` workflow and the only other option are TeX tables which are terrible - all white space, and again, no control on appearance. Plus you can't scale a TeX table on the slide like you can with a plot image. – Corvus Jul 08 '14 at 14:43
  • @Corone have you been able to figure out how to alter the widths and heights of the columns and rows for your example? – h.l.m Jul 21 '14 at 20:22
  • @h.l.m the text is laid out on an integer grid, and the rectangle dimensions are controlled by xmin, xmax, ymin, ymax. If you want to actually specify widths and locations for the text, then you should first generate those columns in the DT and use those as aesthetics. For example create a row, col columns that locate the text. – Corvus Jul 22 '14 at 10:36

0 Answers0