I'm building a visualisation of a dataset using the geom_tile function in ggplot2. I'm almost satisfied with it, however I'd like to add a particular legend to it, but I haven't been able to find a suitable method for this. I'll explain what I mean exactly later on in the post.
Here's the code that I'm currently using, it's probably a huge mess as I'm not proficient in R and basically generated this by trial and error. If anyone is willing to clean it up, knock yourself out :-) .
#Read source data
meta <- read.csv("Dropbox/meta_censored.csv")
#import libraries
library("ggplot2")
library("plyr")
library("reshape2")
library("scales")
library("grid")
#transform and rescale data in prep for later steps
meta.m <- melt(meta)
meta.s <- ddply(meta.m, .(variable), transform,
rescale = scale(value))
#generate categories to sort conditions by colour
meta.s$Category <- meta.s$variable
levels(meta.s$Category) <-
list("1_early" = c("X1", "X2"),
"2_early" = c("X3", "X4", "X5", "X6", "X7"),
"1_late" = c("X10", "X17"),
"2_late" = c("X8", "X9", "X11", "X12", "X14", "X15", "X16"),
"3_late" = "X13",
"4_late" = c("X18", "X19"))
#define colours per category
meta.s$rescaleoffset <- meta.s$rescale + 100*(as.numeric(meta.s$Category)-1)
scalerange <- range(meta.s$rescale)
gradientends <- scalerange + rep(c(0,100,200,300,400,500), each = 2)
colorends <- c("white", "red", "white", "green", "white", "red", "white", "green", "white", "orange", "white", "purple")
#reorder by category
meta.s$variable2 <- reorder(meta.s$variable, as.numeric(meta.s$Category))
#reverse y axis labels (were z-a, now a-z)
flevels <- levels(meta.s$Param)
flevels <- rev(flevels)
#x axis annotation variables
text_early <- textGrob("Early", gp=gpar(fontsize = 5, fontface = "bold", col = "red"))
text_late <- textGrob("Late", gp=gpar(fontsize = 5, fontface = "bold", col = "red"))
#plot heatmap
p <- ggplot(meta.s, aes(variable2, Param)) +
geom_tile(aes(fill = rescaleoffset), colour = "lightgrey") +
#add line to seperate early from late
geom_vline(xintercept = 7.5) +
scale_fill_gradientn(colours = colorends, values = rescale(gradientends)) +
scale_x_discrete("", expand = c(0, 0)) +
scale_y_discrete("", limits = flevels, expand = c(0, 0)) +
theme_grey(base_size = 5) +
theme(legend.position = "right",
axis.ticks = element_blank(),
axis.text.x = element_text(angle = 270, hjust = 0, size = 5, vjust = 0, face = "bold"),
plot.margin = unit(c(1,1,2,1), "lines")) +
annotation_custom(text_early, xmin = 0, xmax = 8, ymin=168.5, ymax = 168.5) +
annotation_custom(text_late, xmin = 8, xmax = 19, ymin=168.5, ymax = 168.5)
gt <- ggplot_gtable(ggplot_build(p))
gt$layout$clip[gt$layout$name == "panel"] <- "off"
grid.draw(gt)
Basically, I'm trying to show values per object in column Param by each value on the x axis. Each value on the x axis represents a different study, with different experimental conditions. I have tried grouping them using this thread, and each group gets a different colour.
Now what I ideally want is that the legend displays the respective solid colour for each category, and not an overall gradient based on the value of each of the cells. Of course it doesn't need to be a legend produced with ggplot2, any other method is accepted as long as it does the trick.
Thanks in advance!