Search code examples
rggplot2geom-bar

Karyogram and SNP with ggplot2 (geom_path, geom_bar, ggbio)


I want to plot a karyogram with SNP markers.
It works with function segments but I want to use ggplot2 package to display an elegant graphic.
enter image description here


  1. ggbio:
    I checked the package ggbio with the function layout_karyogram but the chromosomes are plotted in a vertical position. I didn't find a way to rotate the graph with the name below each chromosome and to write the name of my SNP next to their segment.

enter image description here


  1. geom_bar:
    Then I tried geom_bar from the package ggplot2:
data<-data.frame(chromosome=paste0("chr", 1:4),size=c(100,400,300,200),stringsAsFactors = FALSE)
dat$chromosome<-factor(dat$chromosome, levels = dat$chromosome)
SNP<-data.frame(chromosome=c(1,1,2,3,3,4),Position=c(50,70,250,20,290,110),Type=c("A","A","A","B","B","B"),labels=c("SNP1","SNP2","SNP3","SNP4","SNP5","SNP6"))

p <- ggplot(data=data, aes(x=chromosome, y=size)) + geom_bar( stat="identity", fill="grey70",width = .5)  +theme_bw()
p + geom_segment(data=SNP, aes(x=SNP$chromosome-0.2, xend=SNP$chromosome+0.2, y=SNP$Position,yend=SNP$Position,colour=SNP$Type), size=1) +annotate("text", label =SNP$labels, x =SNP$chromosome-0.5, y = SNP$Position, size = 2, colour= "red")    

enter image description here

The only problem here, it looks more like a barplot than a chromosome. I would like to have rounded extremities. I found someone who got the same problem as I am.


  1. geom_path:
    Instead of using geom_bar, I used geom_path with the option lineend = "round" to get rounded extremities.
ggplot() + geom_path(data=NULL, mapping=aes(x=c(1,1), y=c(1,100)),size=3, lineend="round")   

enter image description here

The shape looks quite good. So I tried to run the code for severals chromosomes.

p <- ggplot()
data<-data.frame(chromosome=paste0("chr", 1:4),size=c(100,400,300,200),stringsAsFactors = FALSE)
for (i in 1:length(data[,1])){
  p <- p + geom_path(data=NULL, mapping=aes(x=c(i,i), y=c(1,data[i,2])), size=3, lineend="round")
}   

enter image description here

It doesn't work, I don't know why but p only save the last chromosome instead of plotting the four chromosomes in my karyogram.


Any suggestions for these problems ?


Solution

  • I would go for geom_segment. The x start/end of the SNP segments are hardcoded (as.integer(chr) -+ 0.05), but otherwise the code is fairly straightforward.

    ggplot() +
      geom_segment(data = data,
                   aes(x = chr, xend = chr, y = 0, yend = size),
                   lineend = "round", color = "lightgrey", size = 5) +
      geom_segment(data = SNP,
                   aes(x = as.integer(chr) - 0.05, xend = as.integer(chr) + 0.05,
                       y = pos, yend = pos, color = type),
                   size = 1) +
      theme_minimal()
    

    enter image description here


    data <- data.frame(chr = paste0("chr", 1:4),
                       size = c(100, 400, 300, 200))
    
    SNP <- data.frame(chr = paste0("chr", c(1, 1, 2, 3, 3, 4)),
                      pos = c(50, 70, 250, 20, 290, 110),
                      type = c("A", "A", "A", "B", "B", "B"))