Dear R-wizards, I'm trying to plot "binned scatterplots", or 2d histograms, if you wish, for a number of groups by using the lattice functionality it works fine for one group at a time, and probably I could find a work-around, but I prefer to do it the elegant way here's an example of what I want, what I tried and where it goes wrong: require(gregmisc) require(lattice) #toy dataset: ds<-data.frame(x=rnorm(3000),y=rnorm(3000),group=rep(factor(c("A","B","C")), 1000)) # this binscatter-function shows what I want, # I just would like to have it as a panel function binscatter<-function(x,y){ col<-rev(gray.colors(5)) breaks=c(1,5,10,100,500,100000) h2d<-hist2d(x=x,y=y,nbins=10,same.scale=T,show=F) image(h2d$x,h2d$y,h2d$counts,breaks=breaks,col=col,axes=T) } # for one group, this works fine A<-subset(ds,group=="A") binscatter(A$x,A$y) # simple xyplot does too (of course) xyplot(y~x|group,data=ds) # but my lattice-ified version of binscatter does not: # 1st attempt panel.binscatter<-function(x,y,subscripts,...){ col<-gray.colors(5) breaks=c(1,5,10,100,500,100000) h2d<-hist2d(x=x,y=y,nbins=10,same.scale=T,show=F) panel.levelplot(h2d$x,h2d$y,h2d$counts,subscripts=1:length(h2d$x),at=breaks, col.regions=col,region=T) } xyplot(y~x|group,data=ds,panel=panel.binscatter) # but, this doesnt work either for one group using levelplot() : Ah2d<-hist2d(A$x,A$y,nbins=10,same.scale=T,show=F) levelplot(Ah2d$counts~Ah2d$x*Ah2d$y) # but this DOES: grid<-expand.grid(x=Ah2d$x,y=Ah2d$y) levelplot(Ah2d$counts~grid$x*grid$y) #2nd attempt doesn't work, I give up.. panel.binscatter<-function(x,y,subscripts,...){ col<-gray.colors(5) breaks=c(1,5,10,100,500,100000) h2d<-hist2d(x=x,y=y,nbins=10,same.scale=T,show=F) grid<-expand.grid(x=h2d$x,y=h2d$y) panel.levelplot(grid$x,grid$y,h2d$counts,subscripts=1:length(h2d$x),at=break s,col.regions=col) } xyplot(y~x|group,data=ds,panel=panel.binscatter) all suggestions welcome, thanks a lot Hans
On 2/6/06, Vermeiren, Hans [VRCBE] <hvermei1 at vrcbe.jnj.com> wrote:> Dear R-wizards, > I'm trying to plot "binned scatterplots", or 2d histograms, if you wish, for > a number of groups by using the lattice functionality > it works fine for one group at a time, and probably I could find a > work-around, but I prefer to do it the elegant way > here's an example of what I want, what I tried and where it goes wrong:If you are doing this for fun, read on. Otherwise, I suggest that you look at the hexbin package (available from bioconductor) for a better solution. The development version (to be released after R 2.3.0) already has a lattice-ified interface called 'hexbinplot'.> require(gregmisc) > require(lattice) > #toy dataset: > ds<-data.frame(x=rnorm(3000),y=rnorm(3000),group=rep(factor(c("A","B","C")), > 1000)) > > # this binscatter-function shows what I want, > # I just would like to have it as a panel function > > binscatter<-function(x,y){ > col<-rev(gray.colors(5)) > breaks=c(1,5,10,100,500,100000) > h2d<-hist2d(x=x,y=y,nbins=10,same.scale=T,show=F) > image(h2d$x,h2d$y,h2d$counts,breaks=breaks,col=col,axes=T) > } > > > # for one group, this works fine > A<-subset(ds,group=="A") > binscatter(A$x,A$y) > > # simple xyplot does too (of course) > xyplot(y~x|group,data=ds) > > # but my lattice-ified version of binscatter does not: > # 1st attempt > panel.binscatter<-function(x,y,subscripts,...){ > col<-gray.colors(5) > breaks=c(1,5,10,100,500,100000) > h2d<-hist2d(x=x,y=y,nbins=10,same.scale=T,show=F) > > panel.levelplot(h2d$x,h2d$y,h2d$counts,subscripts=1:length(h2d$x),at=breaks, > col.regions=col,region=T) > }'image' requires the z-values as a matrix and x,y values as the margins; whereas 'panel.levelplot' needs them as vectors of the same length (so row and column positions are repeated). To call 'panel.levelplot', you need to construct the suitable x and y values. If I were you, I would forget about 'panel.levelplot' and construct a call to 'grid.rect' (in the grid package) which 'panel.levelplot' ends up doing after jumping through a lot of hoops that are irrelevant here. Deepayan> > xyplot(y~x|group,data=ds,panel=panel.binscatter) > > # but, this doesnt work either for one group using levelplot() : > Ah2d<-hist2d(A$x,A$y,nbins=10,same.scale=T,show=F) > levelplot(Ah2d$counts~Ah2d$x*Ah2d$y) > > # but this DOES: > grid<-expand.grid(x=Ah2d$x,y=Ah2d$y) > levelplot(Ah2d$counts~grid$x*grid$y) > > #2nd attempt doesn't work, I give up.. > panel.binscatter<-function(x,y,subscripts,...){ > col<-gray.colors(5) > breaks=c(1,5,10,100,500,100000) > h2d<-hist2d(x=x,y=y,nbins=10,same.scale=T,show=F) > grid<-expand.grid(x=h2d$x,y=h2d$y) > panel.levelplot(grid$x,grid$y,h2d$counts,subscripts=1:length(h2d$x),at=break > s,col.regions=col) > } > > xyplot(y~x|group,data=ds,panel=panel.binscatter) > > all suggestions welcome, thanks a lot > > Hans
-----Original Message----- From: Deepayan Sarkar [mailto:deepayan.sarkar at gmail.com] Sent: Monday, February 06, 2006 9:52 PM To: Vermeiren, Hans [VRCBE] Cc: r-help at lists.R-project.org Subject: Re: panel.levelplot() for 2D histograms On 2/6/06, Vermeiren, Hans [VRCBE] <hvermei1 at vrcbe.jnj.com> wrote:> Dear R-wizards, > I'm trying to plot "binned scatterplots", or 2d histograms, if you wish,for> a number of groups by using the lattice functionality > it works fine for one group at a time, and probably I could find a > work-around, but I prefer to do it the elegant way > here's an example of what I want, what I tried and where it goes wrong:If you are doing this for fun, read on. Otherwise, I suggest that you look at the hexbin package (available from bioconductor) for a better solution. The development version (to be released after R 2.3.0) already has a lattice-ified interface called 'hexbinplot'.>> for fun ? yes and no, I really need this for my job, but otoh,working with R is always fun>> thanks a lot for the pointer to hexbin, that's really what I waslooking for, but i did read on and I'll try the grid.rect hint as well (just for fun)>> thanks again,>> Hans