Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hexViewport does not respect hexbin bounds #20

Open
davidorme opened this issue Jan 18, 2021 · 1 comment
Open

hexViewport does not respect hexbin bounds #20

davidorme opened this issue Jan 18, 2021 · 1 comment

Comments

@davidorme
Copy link

I'm using hexbin to create some plots with overlays and shared axes and have ended up going back to the bare grid commands. I've run into an issue with setting bounds on viewports. The usage for hexViewport is:

hexViewport(x, offset = unit(0,"inches"), mar = NULL,
	    xbnds = NULL, ybnds = NULL, newpage = FALSE,
            clip = "off", vp.name = NULL)

The documentation for reports:

xbnds, ybnds
bounds for x- and y- plotting range; these default to the corresponding slots of x.

where x is a hexbin object. The user can supply xbnds and ybnds to hexbin but these are not respected by hexViewport. The values are in x are first passed through hexbin:::smartBnds which does some smart stuff to do with shape but completely hamstrings any user attempt to control the viewport bounds.

The relevant lines are ( https://github.com/edzer/hexbin/blob/master/R/hexViewport.R#L116):

xyb <- smartBnds(x)
hvp@xscale <- xs <- if(is.null(xbnds)) xyb$xr else xbnds
hvp@yscale <- ys <- if(is.null(ybnds)) xyb$yr else ybnds

So, the user can enforce bounds directly in hexViewport but not - as the documentation suggests - via hexbin. This isn't simple - because the bounds for creating the bins and displaying them are conceptually different. I'm finding that in order to get my expected behaviour, I have to set the bounds in both locations:

library(grid)
l <- grid.layout(nrow = 3, ncol = 1,
        widths = unit(rep_len(1, 3), "null"),
        heights = unit(rep_len(1, 1), "null"),
        default.units = "null", respect = FALSE,
        just="centre")
        
pushViewport(viewport(layout=l))

x <- rnorm(100)
y <- rnorm(100)


# Processed by smartBnds and does not respect the zoomed out bounds given to hexbin
pushViewport(viewport(layout.pos.row=1, layout.pos.col=1))
hx <- hexbin(x, y, xbins=50, xbnds=c(-5,5), ybnds=c(-5,5))
pushHexport(hexViewport(hx, mar=unit(0, 'npc')))
grid.rect()
grid.hexagons(hx)
popViewport()
popViewport()

# No bounds set in hexbin - viewport is zoomed out as expected but 
# poor match to the underlying hexbin representation
pushViewport(viewport(layout.pos.row=2, layout.pos.col=1))
hx <- hexbin(x, y, xbins=50)
pushHexport(hexViewport(hx, mar=unit(0, 'npc'), xbnds=c(-5,5), ybnds=c(-5,5)))
grid.rect()
grid.hexagons(hx)
popViewport()
popViewport()

# Set bounds in both - desired behaviour for neat hexgrid and zoomed out.
pushViewport(viewport(layout.pos.row=3, layout.pos.col=1))
hx <- hexbin(x, y, xbins=50, xbnds=c(-5,5), ybnds=c(-5,5))
pushHexport(hexViewport(hx, mar=unit(0, 'npc'), xbnds=c(-5,5), ybnds=c(-5,5)))
grid.rect()
grid.hexagons(hx)
popViewport()
popViewport()

Honestly, I don't see a simple code fix - but maybe an update to the docs to highlight this?

@TomKellyGenetics
Copy link

I've encountered a similar issue. Changing x@xbnds or x@ybndschanges the axis labels but does not move the boundaries of the plot (likexlimorylim` would be expected to) so they are mislabelled.

If it is possible to pass xlim and ylim directly from hexbinplot() or gplot.hexbin() this would be ideal. My use case is the y-axis and colour scale on a log scale.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants