Search code examples
rggplot2data-visualizationhexagonal-tiles

ggplot2 multiple stat_binhex() plots with different color gradients in one image


I'd like to use ggplot2's stat_binhex() to simultaneously plot two independent variables on the same chart, each with its own color gradient using scale_colour_gradientn().

If we disregard the fact that the x-axis units do not match, a reproducible example would be to plot the following in the same image while maintaining separate fill gradients.

d <- ggplot(diamonds, aes(x=carat,y=price))+
  stat_binhex(colour="white",na.rm=TRUE)+
  scale_fill_gradientn(colours=c("white","blue"),name = "Frequency",na.value=NA)
try(ggsave(plot=d,filename=<some file>,height=6,width=8))

enter image description here

d <- ggplot(diamonds, aes(x=depth,y=price))+
  stat_binhex(colour="white",na.rm=TRUE)+
  scale_fill_gradientn(colours=c("yellow","black"),name = "Frequency",na.value=NA)
try(ggsave(plot=d,filename=<some other file>,height=6,width=8))

enter image description here

I found some conversation of a related issue in ggplot2 google groups here.


Solution

  • Here is another possible solution: I have taken @mnel's idea of mapping bin count to alpha transparency, and I have transformed the x-variables so they can be plotted on the same axes.

    library(ggplot2)
    
    # Transforms range of data to 0, 1. 
    rangeTransform = function(x) (x - min(x)) / (max(x) - min(x))
    
    dat = diamonds
    dat$norm_carat = rangeTransform(dat$carat)
    dat$norm_depth = rangeTransform(dat$depth)
    
    p1 = ggplot(data=dat) +
         theme_bw() +
         stat_binhex(aes(x=norm_carat, y=price, alpha=..count..), fill="#002BFF") +
         stat_binhex(aes(x=norm_depth, y=price, alpha=..count..), fill="#FFD500") +
         guides(fill=FALSE, alpha=FALSE) +
         xlab("Range Transformed Units")
    
    ggsave(plot=p1, filename="plot_1.png", height=5, width=5)
    

    Thoughts:

    1. I tried (and failed) to display a sensible color/alpha legend. Seems tricky, but should be possible given all the legend-customization features of ggplot2.

    2. X-axis unit labeling needs some kind of solution. Plotting two sets of units on one axis is frowned upon by many, and ggplot2 has no such feature.

    3. Interpretation of cells with overlapping colors seems clear enough in this example, but could get very messy depending on the datasets used, and the chosen colors.

    4. If the two colors are additive complements, then wherever they overlap equally you will see a neutral gray. Where the overlap is unequal, the gray would shift to more yellow, or more blue. My colors are not quite complements, judging by the slightly pink hue of the gray overlap cells.

    enter image description here