2013-04-21 4 views
15

Ho un esempio in cui vorrei evidenziare diverse proprietà degli allineamenti di sequenza usando ggplot. Sto usando geom_tile e voglio avere due serie di tessere colorate in modo diverso per due proprietà di punteggio. Sono solo in grado di visualizzarne uno.ggplot2 più scale/legende per estetica, rivisitato

Sono a conoscenza della limitazione di una scala per estetica (and the logic behind it), ma forse qualcuno ha un'idea di come modificarlo per casi come questo in cui avrebbe senso avere scale di colori diverse in una "trama".

Forse con l'aggiunta manualmente il Grobs, ma non saprei da dove cominciare ...

un'ulteriore domanda: per qualche motivo il override.aes=list(shape = "A") non funziona, tutte le idee perché?

uno di più: qualsiasi metodo per ridimensionare il testo in proporzione alla dimensione della piastrella (o viceversa)?

library(ggplot2) 
library(grid) 

pd = data.frame(
    letters = strsplit("AGTGACCGACTATCATAGTGACCCAGAATCATAGTGACCGAGTATGAT", "")[[1]], 
    species = rep(c("Human", "Armadillo", "Porcupine"), each=16), 
    x  = rep(1:16, 3), 
    change = c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
       0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0, 
       0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0), 
    score1 = c(0,0,0,0,0,0,1,1,2,2,2,3,3,3,4,3, 
       0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0, 
       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), 
    score2 = c(0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0, 
       0,0,0,0,2,2,2,2,0,0,0,0,0,0,0,0, 
       0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0) 
) 


ggplot(pd[pd$score1 != 0,], aes(x=x, y=species)) + 
    coord_fixed(ratio = 1.5, xlim=c(0.5,16.5), ylim=c(0.5, 3.5)) + 
    geom_tile(aes(fill=score1)) + 
    scale_fill_gradient2("Score 1", limits=c(0,4),low="#762A83", mid="white", high="#1B7837", guide=guide_colorbar(title.position="top")) + 
    geom_text(data=pd, aes(label=letters, color=factor(change)), size=rel(5), family="mono") + 
    scale_color_manual("Change", values=c("black", "#F2A11F"), labels=c("None", "Some"), guide=guide_legend(direction="vertical", title.position="top", override.aes=list(shape = "A"))) + 
    theme(panel.background=element_rect(fill="white", colour="white"), 
     axis.title = element_blank(), 
     axis.ticks.y = element_blank(), 
     axis.text.y = element_text(family="mono", size=rel(2)), 
     axis.text.x = element_text(size=rel(0.7)), 
     legend.text = element_text(size=rel(0.7)), 
     legend.key.size = unit(0.7, "lines"), 
     legend.position = "bottom", legend.box = "horizontal") + 
    ggtitle("What about Score2?") 

How to add another layer of tiles with different color scale?

risposta

8

Sono riuscito a ottenere un risultato soddisfacente combinando i grobs da due trame generate separatamente. Sono sicuro che la soluzione può essere generalizzata meglio per ospitare diversi indici grob ...

library(ggplot2) 
library(grid) 

pd = data.frame(
    letters = strsplit("AGTGACCGACTATCATAGTGACCCAGAATCATAGTGACCGAGTATGAT", "")[[1]], 
    species = rep(c("Human", "Armadillo", "Porcupine"), each=16), 
    x  = rep(1:16, 3), 
    change = c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
       0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0, 
       0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0), 
    score1 = c(0,0,0,0,0,0,1,1,2,2,2,3,3,3,4,3, 
       0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0, 
       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), 
    score2 = c(0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0, 
       0,0,0,0,2,2,2,2,0,0,0,0,0,0,0,0, 
       0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0) 
) 


p1=ggplot(pd[pd$score1 != 0,], aes(x=x, y=species)) + 
    coord_fixed(ratio = 1.5, xlim=c(0.5,16.5), ylim=c(0.5, 3.5)) + 
    geom_tile(aes(fill=score1)) + 
    scale_fill_gradient2("Score 1", limits=c(0,4),low="#762A83", mid="white", high="#1B7837", guide=guide_colorbar(title.position="top")) + 
    geom_text(data=pd, aes(label=letters, color=factor(change)), size=rel(5), family="mono") + 
    scale_color_manual("Change", values=c("black", "#F2A11F"), labels=c("None", "Some"), guide=guide_legend(direction="vertical", title.position="top", override.aes=list(shape = "A"))) + 
    theme(panel.background=element_rect(fill="white", colour="white"), 
     axis.title = element_blank(), 
     axis.ticks.y = element_blank(), 
     axis.text.y = element_text(family="mono", size=rel(2)), 
     axis.text.x = element_text(size=rel(0.7)), 
     legend.text = element_text(size=rel(0.7)), 
     legend.key.size = unit(0.7, "lines"), 
     legend.position = "bottom", legend.box = "horizontal") + 
    ggtitle("Voila, the Score2!") 

p2=ggplot(pd[pd$score2 != 0,], aes(x=x, y=species)) + 
    coord_fixed(ratio = 1.5, xlim=c(0.5,16.5), ylim=c(0.5, 3.5)) + 
    geom_tile(aes(fill=score2)) + 
    scale_fill_gradient2("Score 2", limits=c(0,3),low="#1B7837", mid="white", high="#762A83", guide=guide_colorbar(title.position="top")) + 
    geom_text(data=pd, aes(label=letters, color=factor(change)), size=rel(5), family="mono") + 
    scale_color_manual("Change", values=c("black", "#F2A11F"), labels=c("None", "Some"), guide=guide_legend(direction="vertical", title.position="top", override.aes=list(shape = "A"))) + 
    theme(panel.background=element_rect(fill="white", colour="white"), 
     axis.title = element_blank(), 
     axis.ticks.y = element_blank(), 
     axis.text.y = element_text(family="mono", size=rel(2)), 
     axis.text.x = element_text(size=rel(0.7)), 
     legend.text = element_text(size=rel(0.7)), 
     legend.key.size = unit(0.7, "lines"), 
     legend.position = "bottom", legend.box = "horizontal") + 
    ggtitle("What about Score2?") 


p1g=ggplotGrob(p1) 
p2g=ggplotGrob(p2) 

combo.grob = p1g 

combo.grob$grobs[[8]] = cbind(p1g$grobs[[8]][,1:4], 
           p2g$grobs[[8]][,3:5], 
           size="first") 

combo.grob$grobs[[4]] = reorderGrob(
          addGrob(p1g$grobs[[4]], 
            getGrob(p2g$grobs[[4]], 
              "geom_rect.rect", 
              grep=TRUE)), 
          c(1,2,5,3,4)) 
grid.newpage() 
grid.draw(combo.grob) 

Two scales in one plot

4

userei dimensioni del testo per indicare la score2:

ggplot(pd[pd$score1 != 0,], aes(x=x, y=species)) + 
    coord_fixed(ratio = 1.5, xlim=c(0.5,16.5), ylim=c(0.5, 3.5)) + 
    geom_tile(aes(fill=score1)) + 
    scale_fill_gradient2("Score 1", limits=c(0,4),low="#762A83", mid="white", high="#1B7837", guide=guide_colorbar(title.position="top")) + 
    geom_text(data=pd, aes(label=letters, size = score2, color=factor(change)), family="mono") + 
    scale_size_continuous(range = c(4, 8)) + 
    scale_color_manual("Change", values=c("black", "#F2A11F"), labels=c("None", "Some"), guide=guide_legend(direction="vertical", title.position="top", override.aes=list(shape = "A"))) + 
    theme(panel.background=element_rect(fill="white", colour="white"), 
     axis.title = element_blank(), 
     axis.ticks.y = element_blank(), 
     axis.text.y = element_text(family="mono", size=rel(2)), 
     axis.text.x = element_text(size=rel(0.7)), 
     legend.text = element_text(size=rel(0.7)), 
     legend.key.size = unit(0.7, "lines"), 
     legend.position = "bottom", legend.box = "horizontal") + 
    ggtitle("What about Score2?") 

enter image description here

AGGIORNAMENTO:

ecco un breve hack, io sono non sono sicuro se questo sia facile da ispezionare visivamente anche se ...

library(ggplot2) 
library(grid) 
library(proto) 

GeomTile2 <- proto(ggplot2:::GeomTile, { 
    reparameterise <- function(., df, params) { 
    df <- .$.super$reparameterise(df, params) 
    if (params$ud == "u") 
     transform(df, ymin = y) 
    else 
     transform(df, ymax = (y-ymin)*0.8 + ymin, ymin = (y-ymin)*0.2 + ymin) 
    } 
    draw <- function(..., ud) {.$.super$draw(..., ud)} 
}) 
geom_tile2 <- function (mapping = NULL, data = NULL, stat = "identity", position = "identity", ..., ud = "u") { 
    GeomTile2$new(mapping = mapping, data = data, stat = stat, position = position, ..., ud = ud) 
} 

ggplot(pd, aes(x=x, y=species)) + 
    coord_fixed(ratio = 1.5, xlim=c(0.5,16.5), ylim=c(0.5, 3.5)) + 
    geom_tile2(aes(fill=score1), ud = "u") + 
    geom_tile2(aes(fill = score2), ud = "d") + 
    scale_fill_gradient2("Score 1", limits=c(0,4),low="#762A83", mid="white", high="#1B7837", guide=guide_colorbar(title.position="top")) + 
    geom_text(data=pd, aes(label=letters, color=factor(change)), size=rel(5), family="mono") + 
    scale_color_manual("Change", values=c("black", "#F2A11F"), labels=c("None", "Some"), guide=guide_legend(direction="vertical", title.position="top", override.aes=list(shape = "A"))) + 
    theme(panel.background=element_rect(fill="white", colour="white"), 
     axis.title = element_blank(), 
     axis.ticks.y = element_blank(), 
     axis.text.y = element_text(family="mono", size=rel(2)), 
     axis.text.x = element_text(size=rel(0.7)), 
     legend.text = element_text(size=rel(0.7)), 
     legend.key.size = unit(0.7, "lines"), 
     legend.position = "bottom", legend.box = "horizontal") + 
    ggtitle("What about Score2?") 

enter image description here

metà superiore indica SCORE1 mentre quello inferiore per score2.

+0

Grazie koshke, ho considerato che, ma non è un segnale visivo sufficienti per rappresentare questa proprietà. Questi allineamenti possono avere un centinaio di caratteri in più e possono contenere diverse dozzine di specie, quindi le lettere sono abbastanza piccole così com'è e spesso non c'è spazio per manipolarle. Inoltre, a volte il punteggio è una variabile continua e sarà davvero difficile distinguere le quantità relative da una sequenza all'altra. Temo di aver bisogno di qualcosa di più 'visivo' – Krizbi

+0

Solo per dare un esempio più reale: [ecco un allineamento completo] (http://i.imgur.com/wB4prkv.png) – Krizbi

+0

@Krizbi Aggiornato per favore trovare . – kohske