19

I have three factors (set1, set2, and set3) for each of about 50 individuals. The values for set1, set2, and set3 are "A","B","C".

I'd like to make a heatmap-like plot of these data but have the legend show the color associated with the values (eg., A='red', B='blue', C='black'). Any suggestions?

M--
  • 25,431
  • 8
  • 61
  • 93
seandavi
  • 2,818
  • 4
  • 25
  • 52

2 Answers2

27

I decided it would be easist to approach this with ggplot2 (for me anyway):

#recreate a data set
dat <- data.frame(person=factor(paste0("id#", 1:50), 
    levels =rev(paste0("id#", 1:50))), matrix(sample(LETTERS[1:3], 150, T), ncol = 3))

library(ggplot2); library(reshape2)
dat3 <- melt(dat, id.var = 'person')
ggplot(dat3, aes(variable, person)) + geom_tile(aes(fill = value),
   colour = "white") + scale_fill_manual(values=c("red", "blue", "black"))

enter image description here

Tyler Rinker
  • 108,132
  • 65
  • 322
  • 519
  • Thanks for a nice solution and I've upvoted but I think there is a typo in library(reshape) where 's' is missing from reshape – discipulus Apr 08 '15 at 13:28
  • Thanks! Can we have more than one legend, infact one legend per row as I have categorical variables that mean different for different rows but I have only four rows of them. – discipulus Apr 08 '15 at 13:41
  • Yes but I don't know how. I'd encourage you to ask a new question. – Tyler Rinker Apr 08 '15 at 14:05
4

A similar plot can also be made with base graphics. Here is one method using the base image function. This sample has a categorical response rather than a numeric one.

dx <- data.frame( Tasks = c('1','2','3','4'),
                  Phase1 = c('Done','Done','Done','WIP'),
                  Phase2 = c('WIP','Done','Done',''),
                  Phase3 = c('','WIP','Done',''))

ff<-factor(as.matrix(dx[,2:4]), 
    levels=c("Done","WIP",""), 
    labels=c("done","wip","-empty-")
)
fx<-matrix(as.numeric(ff), ncol=ncol(dx)-1)

#use labels to assign colors
col<-c(done="darkgreen",wip="orange","-empty-"="black")

imgflip<-function(x) {t(x[nrow(x):1,])}

image(imgflip(fx),
    breaks=(1:(nlevels(ff)+1))-.5,
    col=col[levels(ff)],
    xaxt="n", yaxt="n"
)
axis(2, at=seq(0,1,length.out=nrow(dx)), labels=rev(paste("Task",dx$Tasks)), las=2)
axis(3, at=seq(0,1,length.out=length(names(dx))-1), labels=names(dx)[-1])

which will produce this picture.

sample image

MrFlick
  • 195,160
  • 17
  • 277
  • 295