ggplot2 stat_binhex(): keep bin radius while changing plot size

data-visualization, ggplot2, hexagonal-tiles, plot, r

Solution

Here's the solution to adjust binwidth dynamically. I've included handling for portrait aspect ratios and explicitly stated axis limits.

bins <- function(xMin,xMax,yMin,yMax,height,width,minBins) {
  if(width > height) {
    hbins = ((width/height)*minBins)
    vbins = minBins
  } else if (width < height) { 
    vbins = ((height/width)*minBins)
    hbins = minBins
  } else { 
    vbins = hbins = minBins
    }
  binwidths <- c(((xMax-xMin)/hbins),((yMax-yMin)/vbins))
  return(binwidths)
}

For example this code:

h = 5
w = 5
yMin = min(diamonds$price)
yMax = max(diamonds$price)
xMin = min(diamonds$carat)
xMax = max(diamonds$carat)
minBins = 30

d <- ggplot(diamonds, aes(x = carat, y = price))+ 
  stat_binhex(colour="white", binwidth = bins(xMin,xMax,yMin,yMax,h,w,minBins))+
  ylim(yMin,yMax)+
  xlim(xMin,xMax)
try(ggsave(plot=d,filename=<some file>,height=h,width=w))

Yields: And when we change the width:

w = 8
d <- ggplot(diamonds, aes(x = carat, y = price))+ 
  stat_binhex(colour="white", binwidth = bins(xMin,xMax,yMin,yMax,h,w,minBins))+
  ylim(yMin,yMax)+
  xlim(xMin,xMax)
try(ggsave(plot=d,filename=<some file>,height=h,width=w))

Or change the height:

h = 8
w = 5
d <- ggplot(diamonds, aes(x = carat, y = price))+ 
  stat_binhex(colour="white", binwidth = bins(xMin,xMax,yMin,yMax,h,w,minBins))+
  ylim(yMin,yMax)+
  xlim(xMin,xMax)
try(ggsave(plot=d,filename=<some file>,height=h,width=w))

We can also change the x and y limits:

h = 5
w = 5
xMin = -2

d <- ggplot(diamonds, aes(x = carat, y = price))+ 
  stat_binhex(colour="white", binwidth = bins(xMin,xMax,yMin,yMax,h,w,minBins))+
  ylim(yMin,yMax)+
  xlim(xMin,xMax)
try(ggsave(plot=d,filename=<some file>,height=h,width=w))

Problem

I'd like to a find a way to keep regular hexagons (all sides have equal length) when resizing hexbin plots in ggplot2 without manually adjusting the binwidth parameter. To illustrate: ``` d <- ggplot(diamonds, aes(carat, price))+ stat_binhex(colour="white") try(ggsave(plot=d,filename=<some file>,height=6,width=8)) ``` yields hexagons that at least look regular to the eye: And ``` try(ggsave(plot=d,filename=<some other file>,height=6,width=12)) ``` yields irregular hexagons: The documentation describes the binwidth parameter (e.g. `binwidth = c(1, 1000)`) which specifies bin width. I'd like a function which, when given any plot size, returns the right binwidth settings to create regular hexagons.

Original source