I'm trying to create a picture with points (actually bars, but whatever) in two distinct colours with parallel saturated-to-unsaturated colour scales, with corresponding colourbar legends. I'm most of the way there, but there are a few minor points I can't handle yet.
tl;dr the color scales I get from a red-to-white gradient and a saturated-red-to-completely-unsaturated gradient are not identical.
Set up data: y
will determine both y-axis position and degree of saturation, w
will determine binary colour choice.
set.seed(101)
dd <- data.frame(x=1:100,y=rnorm(100))
dd$w <- as.logical(sample(0:1,size=nrow(dd),
replace=TRUE))
Get packages:
library(ggplot2)
library(cowplot)
library(gridExtra)
I can get the plot I want by allowing alpha (transparency) to vary with y
, but the legend is ugly:
g0 <- ggplot(dd,aes(x,y))+
geom_point(size=8,aes(alpha=y,colour=w))+
scale_colour_manual(values=c("red","blue"))
## + scale_alpha(guide="colourbar") ## doesn't work
I can draw each half of the points by themselves to get a legend similar to what I want:
g1 <- ggplot(dd[!dd$w,],aes(x,y))+
geom_point(size=8,aes(colour=y))+
scale_colour_gradient(low="white",high="red",name="not w")+
expand_limits(x=range(dd$x),y=range(dd$y))
g2 <- ggplot(dd[dd$w,],aes(x,y))+
geom_point(size=8,aes(colour=y))+
scale_colour_gradient(low="white",high="blue",name="w")+
expand_limits(x=range(dd$x),y=range(dd$y))
Now I can use tools from cowplot
to pick off the legends and combine them with the original plot:
g1_leg <- get_legend(g1)
g2_leg <- get_legend(g2)
g0_noleg <- g0 + theme(legend.position='none')
ggdraw(plot_grid(g0_noleg,g1_leg,g2_leg,nrow=1,rel_widths=c(1,0.2,0.2)))
This is most of the way there, but:
- ideally I'd like to squash the two colourbars together (I know I can probably do that with sufficient grid-hacking ...)
- the colours don't quite match; the legend colours are slightly warmer than the point colours ...
Ideas? Or other ways of achieving the same goal?