0

I am using ggplot2 to draw a heatmap with a few color blocks in each line. Like this:

enter image description here

Basically each row will have 200 numbers represent 200 bins, each bin would either have number 1, 2, 3 and 4, which correspond to white, red, blue and orange color.

What I want to do is to align the red block to same column vertically, which means for other rows, have to apply an x-axis offset.

I am using ggplot2 and qplot for this figure, did anyone know how to do the alignment? Thanks a lot.

The code to produce this figure:

library(ggplot2)
library(reshape2)
dat <- read.table('http://wangftp.wustl.edu/~dli/fimo.near.3ins', header=FALSE)
dat$V2 <- factor(dat$V2)
dat.m <- melt(dat, id.vars=c("V1","V2"))
col2=c('white','red','blue','orange')
qplot(variable, V1, fill=col2[value], data=dat.m, geom="tile") + theme_bw() + scale_fill_identity(breaks=col2, guide="legend") + theme(axis.title.x = element_blank(), axis.text.x = element_blank(), axis.text.y = element_blank(), axis.title.y = element_blank(), legend.title = element_text(size=18), legend.text = element_text(size=16),axis.ticks.x = element_blank(),axis.ticks.y = element_blank(), panel.grid=element_blank()) + geom_hline(aes(yintercept=V1))
dli
  • 1,173
  • 3
  • 14
  • 21
  • I assume your data contains an `x` position and ggplot is just respecting that. You will most likely have to transform your data to get the desired plot. Can you post data and the code you used to make this plot (ie create a [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) ) – MrFlick Jun 05 '14 at 14:35
  • Yes, you are right. I added the example code could reproduce my example. Thanks! – dli Jun 05 '14 at 15:13

1 Answers1

1

This is even a bit more tricky because your x-axis values are factors rather than simple numeric values. But as I thought, the only way to really accomplish this is to transform your data. We need to create a new vector shared across all rows to coordinate placement of start of the orange boxes. Here we first calculate the distance of each box from the start of the orange box for each group

offset<-with(dat.m, ave(value, V1, 
    FUN=function(x) seq_along(x)-head(which(x==4),1)))

Now we create a new factor variable in the appropriate order for the offset

dat.m$opos<-factor(offset, levels=seq(from=min(offset),to=max(offset)))

Now we simply plot using this as the x value

qplot(opos, V1, fill=col2[value], data=dat.m, geom="tile") + ...

Comparing this to the original, we see the following plot

comparison of before and after

The boxes seem a bit more narrow because we've essentially zoomed out to see more of all the regions.

MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • This is pretty cool, thanks. I am a little confused about the way you calculated the offset, it that possible you could explain a little bit? Also did you know if I could draw right/left arrows instead of color blocks if I have minus numbers like 2/-2,3/-3,4/-4 values. – dli Jun 05 '14 at 18:29
  • @dli Basically I found all the values for a row and each colored block was essentially indexed by the `variable` column. So I thought of them like numbers 1,2,3,4, etc. I found which index corresponded to the first orange block. Say that was 6. Then I subtracted 6 from each position (6-1, 6-2, 6-3, etc) so that orange was always a 0. – MrFlick Jun 05 '14 at 18:33