GabyLP
GabyLP

Reputation: 3781

ggplot2 heatmap, color scale with conditions

I need to change the colors of the scale of a ggplot in R. My table is:

tt<-data.frame(C1=c(0.4,.5,.5, 0, .8,.8),C2=c(.5,.6,.7, 0, .7,.8), C3=c(.8,.7,.9, 0, .8,.7), 
  C4=c(rep(0,6)), C5=c(0.4,.6,.6, 0, .8,.8),C6=c(0.8,.7,.5, 0, .8,.8), C7=c(0.8,.6,.4, 0, .8,.8))

row.names(tt)<-paste("F", 1:6, sep='')
tt<-as.matrix(tt)

Then I do the reshape:

library(ggplot2)
library(reshape2)
tt_melt <- melt(tt)
tt_melt
colnames(tt_melt)<-c('fila', 'columna', 'performance')

And my graph is a representation of a call center and a metric related to each position:

ggplot(data=tt_melt,
       aes(x=columna, y=fila, fill=performance)) + geom_tile() + 
  geom_text(aes(label=performance), color='white') 
+ theme_minimal(base_size = 12, base_family = "")+
labs(title = 'Performance por posicion en el call')+
  scale_colour_manual(values = c("red","yellow", "green"))
scale_fill_gradient(low = "yellow",  high = "darkgreen")

enter image description here

But it doesn't take the scale. I need to get the 0s in white (because it means that there's nobody in that space) and the rest from red to green. So it's not a truly continuous scale (but should be continuous from red to green). How can I make ggplot take the scale? Also, how can I create a scale that has a condition over the values? And finally, if there's a better way to do this I would be glad to hear about it. Many thanks.

Upvotes: 3

Views: 4450

Answers (2)

hrbrmstr
hrbrmstr

Reputation: 78792

I hope the code formatting is an artifact of the SO paste. I prefer more structured ggplot builds.

You can have far more control if you generate discrete breaks:

library(ggplot2)
library(reshape2) 

tt <- data.frame(C1=c(0.4,.5,.5, 0, .8,.8),
                 C2=c(.5,.6,.7, 0, .7,.8), 
                 C3=c(.8,.7,.9, 0, .8,.7), 
                 C4=c(rep(0,6)), 
                 C5=c(0.4,.6,.6, 0, .8,.8),
                 C6=c(0.8,.7,.5, 0, .8,.8), 
                 C7=c(0.8,.6,.4, 0, .8,.8))

row.names(tt) <- paste("F", 1:6, sep='')
tt <- as.matrix(tt)

tt_melt <- melt(tt) 
colnames(tt_melt) <- c('fila', 'columna', 'performance')

tt_melt$cut <- cut(tt_melt$performance, 
                   breaks=c(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0),
                   labels=as.character(c(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9)),
                   include.lowest=TRUE)

perf_cols <- c("white", colorRampPalette(c("red", "green"))( 9 ))
perf_text_cols <- c("black", rep("white", 9))

gg <- ggplot(data=tt_melt, aes(x=columna, y=fila, fill=cut))
gg <- gg + geom_tile()
gg <- gg + geom_text(aes(label=performance, color=cut)) 
gg <- gg + labs(title = 'Performance por posicion en el call')
gg <- gg + coord_equal()
gg <- gg + scale_colour_manual(values = perf_text_cols)
gg <- gg + scale_fill_manual(values=perf_cols)
gg <- gg + theme_minimal(base_size = 12, base_family = "")
gg <- gg + theme(legend.position="none")
gg

enter image description here

You should prbly hit up Color Brewer and change the ramp. This method also allows you to ensure the text is visible on the white tiles. Also, coord_equal saves you from playing with height/width to get even blocks. You can also add a border to the tiles by adding a color (non aes) parameter to geom_tile.

To keep the 0 values white (per your comment), just use a non aes color like you originally did:

gg <- ggplot(data=tt_melt, aes(x=columna, y=fila, fill=cut))
gg <- gg + geom_tile()
gg <- gg + geom_text(aes(label=performance), color="white") 
gg <- gg + labs(title = 'Performance por posicion en el call')
gg <- gg + coord_equal()
gg <- gg + scale_fill_manual(values=perf_cols)
gg <- gg + theme_minimal(base_size = 12, base_family = "")
gg <- gg + theme(legend.position="none")
gg

enter image description here

Upvotes: 4

rnso
rnso

Reputation: 24535

Try:

ggplot(data=tt_melt, aes(x=columna, y=fila, fill=performance))+
    geom_tile()+ 
    geom_text(aes(label=performance), color='white') +
    theme_minimal(base_size = 12, base_family = "")+
    labs(title = 'Performance por posicion en el call')+
    scale_colour_manual(values = c("red","yellow", "green"))+
    scale_fill_gradient(low = "yellow",  high = "darkgreen")

enter image description here

There were only typing mistakes in your code. There should be a '+' sign at end of the line if you want to continue to next line in ggplot code.

Upvotes: 1

Related Questions