3

I want to create the following type of graph with line, bar and heatmap with a dataset like this:

pos <- 1:40 # X axis 
barvar <- rnorm (40, 5, 2) # y axis for barplot 
linevar <- rnorm (40, 0, 0.5) # yvar for line plot 
heatmapvar <- rep(1:5, 8) # yvar plot for heatmap (color coded) plot 
myd <- data.frame (pos, barvar, linevar, heatmapvar) 

# labeling positions 
label <- c("A", "B", "C", "D", "E", "F", "G", "H", "I")
position <- c(1, 5, 10, 15, 20, 25, 30, 35, 40)

enter image description here

jon
  • 11,186
  • 19
  • 80
  • 132

3 Answers3

3

With this sort of combined plot, it is often easier to make them all separately before trying to join them together:

library(ggplot2)

# line plot
p.line <- ggplot(myd,aes(x=pos)) + 
          geom_line(aes(y=linevar)) + # plot the line using linevar
          # draw the scales. NOTE: position[1] should be 0 not 1.
          scale_x_continuous(breaks=position,labels=label)
# bar plot
p.bar <- ggplot(myd,aes(x=pos)) + 
         geom_bar(aes(y=barvar),stat='identity') +  # plot the bar chart
         scale_y_reverse()                          # reverse y scale

# heat plot
p.heat <- ggplot(myd,aes(x=pos)) + 
          geom_tile(aes(y=-.5,fill=heatmapvar,height=.5)) +  # draw heatmap
          scale_fill_gradient(low="yellow",high="red")       # colour scale

You can use print(p.xxx) to see what they look like.

Now we can combine them all together using grid.arrange in gridExtra:

library(gridExtra)
grid.arrange(p.line,p.heat,p.bar)

It looks like this:

enter image description here

(Note - my bar chart gave a warning because I have a negative barvar - I assume the data you actually are going to use won't have this problem).

Now, the heat map looks a bit ugly and it looks like you want it drawn onto the line map, so we can add it on to the line map instead:

I don't want the heat map to be drawn over the line so I'll set its pos and height myself:

hght <- .25 # just looked nice - you'll have to adjust based on your data
ypos <- min(myd$linevar)-hght
p.line2 <- p.line + 
           geom_tile(aes(x=pos-.5,y=ypos, fill=heatmapvar, height=hght)) +
           scale_fill_gradient(low="yellow",high="red") +               
           opts(legend.position="none")  # <-- turn off the heatmap legend.
# print(p.line2)

Note - I added in a x=pos-.5 because otherwise geom_tile centres the tiles about the x value which doesn't line up (try without the x=pos-.5 to see what I mean).

labeling positions

label <- c("A", "B", "C", "D", "E", "F", "G", "H", "I") position <- c(1, 5, 10, 15, 20, 25, 30, 35, 40)

Now when I arrange these:

grid.arrange(p.line2,p.bar)

It looks like:

enter image description here

As to tweaking colours, adding in titles, etc - you can do that. I'd recommending tweaking the individual graphs to get them how you like, and then only combine them at the end.

The ggplot2 documentation is helpful (although I find that general googling for 'ggplot2 heatmap' (e.g.) is more helpful in terms of getting examples to work off).

mathematical.coffee
  • 55,977
  • 11
  • 154
  • 194
  • Thank you, it is nice..there are still some arrangement problems I would like to work on .. the graphs arranged have different layers ...for example bar variable graph is raised. As the number in x of two graphs should be aligned perfectly, I am not sure they align perfectly, thanks – jon Feb 24 '12 at 12:33
3

Using lattice, set scales=list(relation="free") - this will give you a warning for levelplot(), but the alignment still works fine. If you want it super-aligned, set space="top" in levelplot() to get the legend moved from the right side to the top of heatmap.

Update: I reset some padding and removed labels, as OP requested.

library(lattice)
library(gridExtra)
#within `scales` you can manipulate different parameters of x and y axis
a = xyplot(linevar ~ pos,type="l",col=1,xlab="",ylab="",
           scales=list(relation="free",x=list(draw=F)))
#layout.heights/layout.width can tweak padding for margins
b = barchart(barvar ~ pos,col=1,horizontal=F,xlab="",ylab="",
             scales=list(relation="free",x=list(cex=0.5)),
             par.settings=list(layout.heights=list(bottom.padding = 0)))
#change region colors according to your taste and use `colorkey` to remove legend
col=gray(seq(0.3,0.8,length=6))
c = levelplot(as.matrix(heatmapvar),col.regions=col,colorkey=F,xlab="",ylab="",
              scales=list(relation="free"),
              par.settings=list(layout.heights = list(top.padding =-25)))
grid.arrange(b,a,c)

enter image description here

Geek On Acid
  • 6,330
  • 4
  • 44
  • 64
  • yes, this is quite interesting. But can we remove spaces between the graphs, remove unnecessary labels, and remove the legend in the heatmap plot, thank you for the answer – jon Feb 25 '12 at 18:09
  • Ok @John, I updated the code. Have a dig into lattice help pages, like `xyplot` - you can still tweak a lot of stuff. – Geek On Acid Feb 26 '12 at 23:56
0

Can you think that we can combine all three plots into one ?

Based on mathematical coffee's answer, I tried to do so with tricks - not completely successful however I think experts will help me to circumvent the deficiencies.

pos <- 1:40 # X axis
barvar <-  c(-1 * rnorm (40, 5, 2)) # y axis for barplot
linevar <- rnorm (40, 0, 0.5) # yvar for line plot
heatmapvar <- rep(1:5, 8) # yvar plot for heatmap (color coded) plot
myd <- data.frame (pos, barvar, linevar, heatmapvar)

# labeling positions
label <- c("A", "B", "C", "D", "E", "F", "G", "H", "I")
position <- c(1, 5, 10, 15, 20, 25, 30, 35, 40)

hght <- .25 # just looked nice - you'll have to adjust based on your data
ypos <- min(myd$linevar)-hght

require(ggplot2)
p.line <- ggplot(myd,aes(x=pos)) +
          geom_line(aes(y=linevar)) + # plot the line using linevar
          # draw the scales. NOTE: position[1] should be 0 not 1.
          scale_x_continuous(breaks=position,labels=label)
# bar plot
p.bar <- ggplot(myd,aes(x=pos)) +
         geom_bar(aes(y=barvar),stat='identity') +  # plot the bar chart
         scale_y_reverse()

p.line2 <- p.line +
           geom_tile(aes(x= pos-.5,y=ypos, fill=heatmapvar, height=hght)) +
           scale_fill_gradient(low="yellow",high="red") +
           opts(legend.position="none")  # <-- turn off the heatmap legend.

#
 print(p.line2)
p.line3 <- p.line2 + geom_bar(aes(y=barvar, ymax= -1),stat='identity')

print(p.line3)

enter image description here

There are major two - three deficiencies -

(1) In could not make the start point of bars from - 2

(2) I want to suppress - negative number (I just use the trick to convert the bars to negative)

SHRram
  • 4,127
  • 7
  • 35
  • 53