Multiple legends in a plot with geom_tile

2019-05-22 20:21发布

问题:

I have two different data frame: P1 and P2. Each of these data frame have 3 different columns: N1, N2 and a value (mean_RMSE). N1 and N2 are between 15 and 120 and for a line, N2 is always lower than N1.

If I plot P1, this is what I get:

p <- ggplot()
p <- (p
      + geom_tile(data=P1, aes(x=as.numeric(N1), y=as.numeric(N2), fill=mean_RMSE))
)

But my aim is to plot P1 and P2 on the same plot:

p <- ggplot()
p <- (p
      + geom_tile(data=P1, aes(x=as.numeric(N1), y=as.numeric(N2), fill=mean_RMSE))
      + geom_tile(data=P2, aes(x=as.numeric(N2), y=as.numeric(N1), fill=mean_RMSE))
)

I don't know how to change the color for P2. For example, I want a blue color range for P1 and a red color range for P2, to easily distinguish P1 from P2.

scale_fill_gradient change the color of P1 and P2 (I still can't distinguish them) and if I add "colour" in geom_tile, I juste have two different contours:

p <- ggplot()
p <- (p
      + geom_tile(data=psSST_T[[1]], aes(x=as.numeric(N1), y=as.numeric(N2), fill=mean_RMSE, colour="red"))
      + geom_tile(data=psT_SST[[1]], aes(x=as.numeric(N2), y=as.numeric(N1), fill=mean_RMSE, colour="blue")))

In fact, I want two different legends for P1 and P2.

Can someone help me?

回答1:

I'm assuming that you want to use different color schemes for P1 and P2 data frames. You can achieve this by combining fill=factor(data_frame) with alpha=mean_RMSE. Then you can add 2 legends using gridExtra and gtable packages.

# making up data
P1 <- data.frame(N1=as.integer(runif(100, 0, 12))*10, 
                 N2=as.integer(runif(100, 0, 12))*10,
                 mean_RMSE=rnorm(100, 0, 1), 
                 data_frame=rep("P1", 100))
P2 <- data.frame(N1=as.integer(runif(100, 0, 12))*10, 
                 N2=as.integer(runif(100, 0, 12))*10,
                 mean_RMSE=rnorm(100, 0, 1), 
                 data_frame=rep("P2", 100))
d <- rbind(P1, P2)

library(ggplot2)
library(gridExtra)
library(gtable)

(g_main <- ggplot(d, aes(N1, N2, fill=data_frame, alpha=mean_RMSE)) + geom_tile() + 
           scale_fill_manual("", values = c("#CC0000", "#0000FF"), drop = FALSE))

## create dummy plots to create legends of 2 different color schemes

(g_dummy1 <- ggplot(subset(d, data_frame=="P1"), aes(N1, N2, fill=mean_RMSE)) + geom_tile() +
             scale_fill_gradientn(name = "Mean RMSE \n(P1)", colours=c("#CC0000", "white")))
(g_dummy2 <- ggplot(subset(d, data_frame=="P2"), aes(N1, N2, fill=mean_RMSE)) + geom_tile() +
             scale_fill_gradientn(name = "Mean RMSE \n(P2)", colours=c("#0000FF", "white")))

This is a function found in this post to create a legend grob.

g_legend<-function(a.gplot){
  tmp <- ggplot_gtable(ggplot_build(a.gplot))
  leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
  legend <- tmp$grobs[[leg]]
  legend
}

Now use this function to create 2 legend grobs with different color schemes, then use grid.arrange to put everything together:

legend1 <- g_legend(g_dummy1)
legend2 <- g_legend(g_dummy2)
grid.arrange(g_main+theme(legend.position = 'none'), legend1, legend2,
             ncol=3, widths=c(4/6, 1/6, 1/6))



回答2:

This is beautiful and brilliant. I may be little confused about what is going on with the legends, but it seems like in the main graph the blue and red are graphed using the same intensity scale, but on the subgraphs where the legends come from the intensity scale is only from the graphed data. If this is the case then the legends are a little off. If I'm right, then I think it can be fixed by adding limits to the subplots:

(g_dummy1 <- ggplot(subset(d, data_frame=="P1"), aes(N1, N2, fill=mean_RMSE)) + geom_tile()
+ scale_fill_gradientn(name = "Mean RMSE \n(P1)", colours=c("#CC0000",   "white"), 
limits  = c(min(d$mean_RMSE), max(d$mean_RMSE)) ))

(g_dummy2 <- ggplot(subset(d, data_frame=="P2"), aes(N1, N2, fill=mean_RMSE)) + geom_tile() 
+ scale_fill_gradientn(name = "Mean RMSE \n(P2)", colours=c("#0000FF", "white"), 
limits  = c(min(d$mean_RMSE), max(d$mean_RMSE))))

Which gives this:

enter image description here

PLEASE tell me if you disagree. Thanks for posting this it is wonderful!

-Dustin



标签: r ggplot2