Controlling heatmap colors with ggplot2

One of the most popular posts on this blog is the very first one, solving the issue of mapping certain ranges of values to particular colors in heatmaps. Given the abundance of ggplot2 usage in R plotting, I thought I’d give it a try and do similar job within the context of graphics grammar.

## required packages (plot, melt data frame, and rolling function)
library(ggplot2)
library(reshape)
library(zoo)

## repeat random selection
set.seed(1)

## create 50x10 matrix of random values from [-1, +1]
random_matrix <- matrix(runif(500, min = -1, max = 1), nrow = 50)

## set color representation for specific values of the data distribution
quantile_range <- quantile(random_matrix, probs = seq(0, 1, 0.2))

## use http://colorbrewer2.org/ to find optimal divergent color palette (or set own)
color_palette <- colorRampPalette(c("#3794bf", "#FFFFFF", "#df8640"))(length(quantile_range) - 1)

## prepare label text (use two adjacent values for range text)
label_text <- rollapply(round(quantile_range, 2), width = 2, by = 1, FUN = function(i) paste(i, collapse = " : "))

## discretize matrix; this is the most important step, where for each value we find category of predefined ranges (modify probs argument of quantile to detail the colors)
mod_mat <- matrix(findInterval(random_matrix, quantile_range, all.inside = TRUE), nrow = nrow(random_matrix))

## remove background and axis from plot
theme_change <- theme(
 plot.background = element_blank(),
 panel.grid.minor = element_blank(),
 panel.grid.major = element_blank(),
 panel.background = element_blank(),
 panel.border = element_blank(),
 axis.line = element_blank(),
 axis.ticks = element_blank(),
 axis.text.x = element_blank(),
 axis.text.y = element_blank(),
 axis.title.x = element_blank(),
 axis.title.y = element_blank()
)

## output the graphics
ggplot(melt(mod_mat), aes(x = X1, y = X2, fill = factor(value))) +
geom_tile(color = "black") +
scale_fill_manual(values = color_palette, name = "", labels = label_text) +
theme_change

Result of the quantile color representation:

We can predefine ranges, and create skewed colorsets:
Trick was to discretize the matrix of continuous values. Alternatively, you can use “breaks” argument in functions such as scale_fill_gradientn, but such method will assign continuous list of colors within set range.

Cheers.

About these ads

6 thoughts on “Controlling heatmap colors with ggplot2

    • It’s part of the ggplot2 package. Check if you have the latest version.

      > library(ggplot2)
      > theme
      function (..., complete = FALSE) 
      {
          elements <- list(...)
          mapply(validate_element, elements, names(elements))
          structure(elements, class = c("theme", "gg"), complete = complete)
      }
      <environment: namespace:ggplot2>
      > sessionInfo()
      R version 2.15.2 (2012-10-26)
      Platform: i386-apple-darwin9.8.0/i386 (32-bit)
      
      locale:
      [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
      
      attached base packages:
      [1] stats     graphics  grDevices utils     datasets  methods   base     
      
      other attached packages:
      [1] ggplot2_0.9.2.1
      
      loaded via a namespace (and not attached):
       [1] colorspace_1.2-0   dichromat_1.2-4    digest_0.5.2       grid_2.15.2       
       [5] gtable_0.1.1       labeling_0.1       MASS_7.3-22        memoise_0.1       
       [9] munsell_0.4        plyr_1.7.1         proto_0.3-9.2      RColorBrewer_1.0-5
      [13] reshape2_1.2.1     scales_0.2.2       stringr_0.6.1   
      
      • Thank you for your fast reply. As you supposed i was using a old version of ggplot2. Now everthing works fine.

  1. The question didn’t show up as expected due to format problem in previous post. I was wondering how to predefine ranges as you have shown in the second heatmap

    • You can change interval to color relationship by modifying quantile_range and color_palette objects. Each sliding pair within quantile_range corresponds to a single color (upper and lower boundary).

      To change the colors within ranges, you’d write something like:

      color_palette[4] <- "#a95af6"
      

      …, which would generate a heatmap like this:

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s