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