ggplot2 múltiplas escalas / lendas por estética revisitada

Eu tenho um exemplo onde gostaria de destacar várias propriedades de alinhamentos de seqüência usando ggplot. Eu estou usando geom_tile e quero ter dois conjuntos de peças de colors diferentes para duas propriedades de pontuação. Eu só sou capaz de visualizar um.

Estou ciente da limitação de uma escala por estética ( e a lógica por trás dela ), mas talvez alguém tenha uma ideia de como hackear isso para casos como este, onde faria sentido ter escalas de colors diferentes em uma “trama”.

Talvez com a adição manual dos Grobs, mas eu não saberia por onde começar …

uma pergunta adicional: por alguma razão, o override.aes=list(shape = "A") não funciona, alguma idéia por quê?

mais um: qualquer método para dimensionar o texto proporcionalmente ao tamanho do bloco (ou vice-versa)?

 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?") 

Como adicionar outra camada de telhas com escala de cores diferente?

Consegui obter um resultado satisfatório combinando grobs de dois charts gerados separadamente. Tenho certeza de que a solução pode ser generalizada melhor para acomodar diferentes índices de 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) 

Duas escalas em um lote

Eu usaria o tamanho do texto para indicar o 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?") 

insira a descrição da imagem aqui

ATUALIZADA:

Aqui está um hack rápido, eu não tenho certeza se isso é fácil de inspecionar visualmente embora …

 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?") 

insira a descrição da imagem aqui

A metade superior indica pontuação1 enquanto a inferior para pontuação2.