Attempting to overlay color plots (something like below) using ggplot2
Trying to use geom_tile but ggplot doesnt allow me to add 2 color scales. Here is an example code.
df <- data.frame(expand.grid(1:5,1:5))
df$z1 <- runif(nrow(df))
df$z2 <- runif(nrow(df))
g1 <- ggplot(df,aes(Var1,Var2)) + theme_bw()
#layer 1
g11 <- g1 + geom_tile(aes(fill=z1),alpha=0.5) + scale_fill_gradient(low="white", high="red")
#layer 2
g12 <- g1 + geom_tile(aes(fill=z2),alpha=0.5) + scale_fill_gradient(low="white", high="green")
g11
g12
One way to possible do this is to make the 2 layers as different groups. But the outcome just doesn't look intuitive.
mdf=melt(df,'id'=1:2)
g2 <- ggplot(mdf,aes(Var1,Var2,fill = factor(variable),alpha = value)) +
geom_tile() + scale_fill_manual(values = c('red','green')) + theme_bw()
g2
You're really close: just don't divide z1 and z2 by 2.
There is another issue to consider though. If z1 and z2 are not on the same scale, should you use a common scale for both, or should you scale them independently? The result is (can be) different, as illustrated below.
gg.overlay <- function(df) { # produces 2 color channels and the overlay
require(ggplot2)
require(gridExtra)
gg.z1 <- ggplot(df, aes(x,y))+
geom_tile(fill=rgb(red=df$z1.scale,green=0,blue=0))+
scale_x_continuous(expand=c(0,0))+
scale_y_continuous(expand=c(0,0))+
coord_fixed()
gg.z2 <- ggplot(df, aes(x,y))+
geom_tile(fill=rgb(red=0,green=df$z2.scale,blue=0))+
scale_x_continuous(expand=c(0,0))+
scale_y_continuous(expand=c(0,0))+
coord_fixed()
gg <- ggplot(df, aes(x,y))+
geom_tile(fill=rgb(red=df$z1.scale,green=df$z2.scale,blue=0))+
scale_x_continuous(expand=c(0,0))+
scale_y_continuous(expand=c(0,0))+
coord_fixed()
library(gridExtra)
grid.arrange(gg.z1, gg.z2, gg, ncol=3)
}
Using an example slightly closer to the image in your question:
library(mvtnorm) # just for this example
df <- expand.grid(x=seq(-3,3,len=100),y=seq(-3,3,len=100))
df$z1 <- with(df,dmvnorm(cbind(x,y),mean=c(0,0),sigma=matrix(c(1,-1,-1,2),nc=2)))
df$z2 <- with(df,3*dmvnorm(cbind(x,y),mean=c(0,0),sigma=matrix(c(1,0,0,1),nc=2)))
# scale z1 and z2 together
max.z <- with(df,max(z1,z2))
min.z <- with(df,min(z1,z2))
df$z1.scale <- with(df, (z1-min.z)/(max.z-min.z))
df$z2.scale <- with(df, (z2-min.z)/(max.z-min.z))
gg.overlay(df)
# scale z1 and z2 separately
df$z1.scale <- with(df, (z1-min(z1))/diff(range(z1)))
df$z2.scale <- with(df, (z2-min(z2))/diff(range(z2)))
gg.overlay(df)
In the first case the reds are muted because the z1
intensities are lower than the z2
intensities. In the second case we scale them separately, so the reds are more vibrant. It's not clear which is the "correct" method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With