I am trying to create a complete set of plots using facet_wrap
from the ggplot2 package in R.
As a simplified example I used a subset of the dataset mpg included in ggplot2
library(plyr)
library(ggplot2)
library(gtable)
library(gridExtra)
myData = subset(mpg, manufacturer == "audi" | manufacturer == "chevrolet")
myData = droplevels(myData)
Here is my code to plot the data:
p = ggplot(myData, aes(x=hwy, y=cty, colour=model) )
p = p + facet_wrap( ~ manufacturer)#, scales="free") # sets panel division
p = p + geom_point(size = 3) # sets points aspect
p = p + geom_smooth(stat="identity")
print(p)
Now here comes the tricky part... I have another dataframe 'indivParam' with extra information that I would like to display as a table on the plot. Let's say this silly one:
indivParam = ddply(myData, .(manufacturer , model), summarize,
var1 = unique(class),
var2 = round(mean(displ)),
var3 = round(mean(cyl)))
What I am trying to do is to add a sub-table on each panel, with info extracted from indivParam. For example add the following table on the first panel of the plot:
tg = tableGrob(subset(indivParam, manufacturer == "audi"),
show.rownames=FALSE, gp=gpar(fontsize=8, lwd=2),
xmin=15, xmax=30, ymin=10, ymax=20)
grid.newpage()
grid.draw(tg)
I tried several options...
using
annotate()
but this argument does not pass dataframes...using
annotation_custom()
as suggested in this thread : Adding table within the plotting region of a ggplot in rp1 = p + annotation_custom(tableGrob(indivParam, show.rownames=FALSE, gp=gpar(fontsize=8, lwd=2)), xmin=15, xmax=30, ymin=10, ymax=20) print(p1)
This does not work either because it displays the entire table on each panel, instead of a sub-table with data related to each panel ()
Finally, after reading the examples on the 'tableGrob' doc page, I tried to create one grid with all the sub-table grobs and simply superimpose it on the plot:
lg <- lapply(as.character(unique(indivParam$manufacturer)), function(x) tableGrob( as.data.frame(dlply(indivParam, .(manufacturer))[x]), name="test",show.rownames=FALSE, gp=gpar(fontsize=8, lwd=2))) grid.newpage() print(p) grid.draw(do.call(arrangeGrob, lg))
But then, the organization does not match the one used by facet.., and I suspect that even if I could put the two tables next to each other, they would be centered and would hide the plots...
Is there any way I could improve this last attempt by choosing the position of the sub-tables? Or is there an even better way to solve this issue? An obvious one would be to use a geom_table()
but I don't think this geom exist (yet)...
Any help/hint will be much appreciated!! :-)
geom_table
would be most natural, but it's unclear whether such a geom would fit well in plot panels (typically tables take a lot of space and would often hide data in other layers). Short of having a smart positioning function (minimise overlap) they're usually best placed manually imho. – Lati