[med-svn] [r-cran-hexbin] 06/08: New upstream version 1.27.1
Andreas Tille
tille at debian.org
Thu Oct 19 16:40:16 UTC 2017
This is an automated email from the git hooks/post-receive script.
tille pushed a commit to branch master
in repository r-cran-hexbin.
commit 11aaf5242e972bb859c50698aff8c318eb203da4
Author: Andreas Tille <tille at debian.org>
Date: Thu Oct 19 18:36:26 2017 +0200
New upstream version 1.27.1
---
ChangeLog | 65 ++++
DESCRIPTION | 25 ++
MD5 | 77 +++++
NAMESPACE | 93 +++++
R/BTC.R | 268 +++++++++++++++
R/BTY.R | 266 +++++++++++++++
R/HO.R | 267 +++++++++++++++
R/LINGRAY.R | 111 ++++++
R/LOCS.R | 266 +++++++++++++++
R/MAG.R | 266 +++++++++++++++
R/RB.R | 266 +++++++++++++++
R/grid.hexagons.R | 366 ++++++++++++++++++++
R/grid.hexlegend.R | 157 +++++++++
R/hbox.R | 83 +++++
R/hdiffplot.R | 331 ++++++++++++++++++
R/hexPlotMA.R | 196 +++++++++++
R/hexViewport.R | 253 ++++++++++++++
R/hexbin.s4.R | 355 +++++++++++++++++++
R/hexbinList.R | 106 ++++++
R/hexbinplot.R | 777 ++++++++++++++++++++++++++++++++++++++++++
R/hexpanel.R | 37 ++
R/hexplom.R | 352 +++++++++++++++++++
R/hexutil.R | 122 +++++++
R/lattice.R | 744 ++++++++++++++++++++++++++++++++++++++++
R/smoothHexbin.R | 46 +++
README.md | 5 +
TODO | 36 ++
build/vignette.rds | Bin 0 -> 267 bytes
data/NHANES.rda | Bin 0 -> 162590 bytes
debian/README.test | 8 -
debian/changelog | 11 -
debian/compat | 1 -
debian/control | 24 --
debian/copyright | 36 --
debian/docs | 1 -
debian/examples | 1 -
debian/rules | 6 -
debian/source/format | 1 -
debian/tests/control | 3 -
debian/tests/run-unit-test | 18 -
debian/watch | 2 -
inst/doc/hexagon_binning.R | 233 +++++++++++++
inst/doc/hexagon_binning.Rnw | 498 +++++++++++++++++++++++++++
inst/doc/hexagon_binning.pdf | Bin 0 -> 386701 bytes
man/NHANES.Rd | 52 +++
man/colramp.Rd | 60 ++++
man/erode.hexbin.Rd | 86 +++++
man/getHMedian.Rd | 34 ++
man/gplot.hexbin.Rd | 145 ++++++++
man/grid.hexagons.Rd | 199 +++++++++++
man/grid.hexlegend.Rd | 81 +++++
man/hboxplot.Rd | 98 ++++++
man/hcell2xy.Rd | 63 ++++
man/hcell2xyInt.Rd | 47 +++
man/hdiffplot.Rd | 134 ++++++++
man/hexGraphPaper.Rd | 66 ++++
man/hexList.Rd | 46 +++
man/hexMA.loess.Rd | 42 +++
man/hexTapply.Rd | 58 ++++
man/hexVP-class.Rd | 76 +++++
man/hexVP.abline.Rd | 44 +++
man/hexViewport.Rd | 55 +++
man/hexbin.Rd | 110 ++++++
man/hexbinplot.Rd | 222 ++++++++++++
man/hexplom.Rd | 96 ++++++
man/hexpolygon.Rd | 78 +++++
man/hsmooth-methods.Rd | 28 ++
man/inout.hex.Rd | 31 ++
man/list2hexList.Rd | 25 ++
man/old-classes.Rd | 24 ++
man/optShape.Rd | 50 +++
man/panel.hexboxplot.Rd | 49 +++
man/panel.hexgrid.Rd | 21 ++
man/panel.hexloess.Rd | 41 +++
man/plotMAhex.Rd | 133 ++++++++
man/pushHexport.Rd | 29 ++
man/smooth.hexbin.Rd | 84 +++++
src/hbin.f | 88 +++++
src/hcell.f | 62 ++++
src/herode.f | 245 +++++++++++++
src/hsm.f | 114 +++++++
tests/hdiffplot.R | 36 ++
tests/hdiffplot.Rout.save | 155 +++++++++
tests/hray.R | 31 ++
tests/hray.Rout.save | 52 +++
tests/large.R | 39 +++
tests/large.Rout.save | 60 ++++
tests/viewp-ex.R | 21 ++
tests/viewp-ex.Rout.save | 42 +++
vignettes/hexagon_binning.Rnw | 502 +++++++++++++++++++++++++++
90 files changed, 10521 insertions(+), 112 deletions(-)
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..c87ce2f
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,65 @@
+2009-08-09 Nicholas Lewin-Koh <nikko at hailmail.net>
+ * R/grid.hexagons.R removed break statements, switch fails. Cow
+ lattice and centroid can ramp colors. Bug submitted by Ricardo
+ DeLemos" <lemos at soe.ucsc.edu>
+ * man/hexVP-class.Rd Shape slot was not documented
+
+2009-02-26 Nicholas Lewin-Koh <nikko at hailmail.net>
+ * R/grid.hexagons.R fixed bad if construct
+ * R/hexbin.s4.R changed xlab and ylab signatures in class hexbin
+ from character to vector, patch submitted by Don Armstrong <don at donarmstrong.com>
+
+2008-04-28 Martin Maechler <maechler at stat.math.ethz.ch>
+
+ * DESCRIPTION (Version): 1.13.4
+
+ * man/*.Rd: fixes to several man pages;
+ note that gplot.hexbin() now is *deprecated* !
+
+2008-03-18 Patrick Aboyoun <paboyoun at fhcrc.org>
+
+ * man/panel.hexboxplot, man/panel.hexgrid, man/panel.hexloess: Added more information to man files.
+ * R/hexbinplot.R (panel.hexboxplot): removed unused singles argument.
+
+2008-03-12 Patrick Aboyoun <paboyoun at fhcrc.org>
+
+ * R/hexViewport.R (hexVP.abline): Fixed the handling of non-model objects as input.
+
+2008-02-28 Patrick Aboyoun <paboyoun at fhcrc.org>
+
+ * R/hexPlotMA.R (plotMAhex): Require users to specify status explicitly
+ rather than as the component MA$genes$Status
+ * R/hexPlotMA.R (plotMAhex): Replaced support of Biobase class exprSet with
+ ExpressionSet
+
+2006-09-28 Martin Maechler <maechler at stat.math.ethz.ch>
+
+ * NAMESPACE: add full list of colorspace dependencies
+
+2005-07-26 Martin Maechler <maechler at stat.math.ethz.ch>
+
+ * R/hexViewport.R (smartBnds): some rationalization
+ * R/hexViewport.R (rname): dito
+
+2005-07-19 Martin Maechler <maechler at stat.math.ethz.ch>
+
+ * DESCRIPTION (Version): 1.3.1 (not to confuse with the previous one).
+
+ * man/gplot.hexbin.Rd: fix typo and usage for S4method
+
+ * R/hexPlotMA.R (hexMA.loess): add argument 'n'
+
+ * R/hexViewport.R (hexVP.loess): add argument 'n'; other "white
+ space cosmetic" in file
+
+2005-10-21 Nicholas Lewin-Koh <nikko at hailmail.net>
+
+ * added Deepayan Sarkar's hexbinplot.R function for lattice hexbin
+ plots
+
+ * Added my Hexplom function based on Deepayan's code
+
+2005-10-27 Nicholas Lewin-Koh <nikko at hailmail.net>
+
+ * Added more panel functions, for hexboxplots and hdiffplots.
+
diff --git a/DESCRIPTION b/DESCRIPTION
new file mode 100644
index 0000000..8fd91b5
--- /dev/null
+++ b/DESCRIPTION
@@ -0,0 +1,25 @@
+Package: hexbin
+Version: 1.27.1
+Date: 2015-08-19
+Title: Hexagonal Binning Routines
+Author: Dan Carr <dcarr at voxel.galaxy.gmu.edu>, ported by Nicholas
+ Lewin-Koh and Martin Maechler <maechler at stat.math.ethz.ch>,
+ contains copies of lattice functions written by Deepayan Sarkar
+ <deepayan.sarkar at r-project.org>
+Maintainer: Edzer Pebesma <edzer.pebesma at uni-muenster.de>
+Depends: R (>= 2.0.1), methods
+Imports: lattice, grid, graphics, grDevices, stats, utils
+Suggests: marray, affy, Biobase, limma
+Description: Binning and plotting functions for hexagonal bins. Now
+ uses and relies on grid graphics and formal (S4) classes and
+ methods.
+Collate: lattice.R BTC.R BTY.R grid.hexagons.R grid.hexlegend.R hbox.R
+ hdiffplot.R hexbinList.R hexbinplot.R hexbin.s4.R hexpanel.R
+ hexplom.R hexPlotMA.R hexutil.R hexViewport.R HO.R LINGRAY.R
+ LOCS.R MAG.R RB.R smoothHexbin.R
+License: GPL-2
+NeedsCompilation: yes
+URL: http://github.com/edzer/hexbin
+Packaged: 2015-08-19 15:11:53 UTC; edzer
+Repository: CRAN
+Date/Publication: 2015-08-19 17:28:20
diff --git a/MD5 b/MD5
new file mode 100644
index 0000000..fdd6c73
--- /dev/null
+++ b/MD5
@@ -0,0 +1,77 @@
+b8c6e7f6b0230cdf61f0976d387c7a44 *ChangeLog
+58f0420f8288b4faae52aba21669bc3d *DESCRIPTION
+9129a733a21f780d50b1c3bb85da0047 *NAMESPACE
+98a77d0235bb074f09aa7675358b8650 *R/BTC.R
+b8083617bec9ef2a20bf2fb31d1f50cb *R/BTY.R
+def8a3ae791d6214f8093069780971a3 *R/HO.R
+e54503901b17f4b00ab192bef093ff18 *R/LINGRAY.R
+9220834650597d3f9a3c2f5a38fb2fc6 *R/LOCS.R
+47006284b4bc42824409e49cd3ebb6e7 *R/MAG.R
+c25363a22b3f824d1f25997179b74434 *R/RB.R
+97262cc9f616661bf71e4686225f6c17 *R/grid.hexagons.R
+cd88d10aa75a6666b296efff0ac1f355 *R/grid.hexlegend.R
+503b110bf985d5c12a0d514c333dc81e *R/hbox.R
+ad4a901fb8fc48deb4f76ad3d797ecd9 *R/hdiffplot.R
+d53fcb4dabb71c0154e881648c6b13da *R/hexPlotMA.R
+e5cb8c5f3ba8f183d4c69e50f153f845 *R/hexViewport.R
+48ab7518d22b3310dab41acae327c743 *R/hexbin.s4.R
+5d66d35fa92d45957684ee3375513e28 *R/hexbinList.R
+ae5724baa7c3661621ed0018287fc6ca *R/hexbinplot.R
+53e8c6ea014e06b21e56b8e447a0dad5 *R/hexpanel.R
+249d47000fdc8b641cf6ed2ee6f640bb *R/hexplom.R
+0b7181a5ae4cbc780f46041886fc80e8 *R/hexutil.R
+acf4489ea175f01eb1659a420183e155 *R/lattice.R
+449d6bbfb6927f39383b586ffce19eb1 *R/smoothHexbin.R
+408e6e0599f15c991715933ddd85400f *README.md
+53e586900ba0c452c12ec7aed3d20295 *TODO
+dd1765c586720d0a4c7c5064fce7da74 *build/vignette.rds
+cfa9343134507d8eaf7386167ea1243d *data/NHANES.rda
+a6e0f6f67abc1c4d94ad6b2d33860fe2 *inst/doc/hexagon_binning.R
+ed9dbcabcbb9240445d6dac2de22ba5f *inst/doc/hexagon_binning.Rnw
+4550e584d1ad491edcb547bd4ec28845 *inst/doc/hexagon_binning.pdf
+3b3cb098160c79abc4d739397d315ff3 *man/NHANES.Rd
+bfc5169b22c653bb5912e9c3e92f3207 *man/colramp.Rd
+94a1639600897389f489b6b836362d82 *man/erode.hexbin.Rd
+47a11326b5056014da626fe8c3c5b8e8 *man/getHMedian.Rd
+651ab732e881463b6516824c162e35ac *man/gplot.hexbin.Rd
+4f14ff188dcc89ced1434511b0da5dc0 *man/grid.hexagons.Rd
+6e12f30832b4d71515a91bb8c448049d *man/grid.hexlegend.Rd
+5f2695c8af33d84b154a61e3463859e9 *man/hboxplot.Rd
+eb4f91c7c9c4482122d7c9ee209e93b6 *man/hcell2xy.Rd
+9a215a3b0ff1077d865688a5d9a40921 *man/hcell2xyInt.Rd
+29e7649124c53711586904d9c556f53e *man/hdiffplot.Rd
+f49d784dfab4e373b90f6399c511235f *man/hexGraphPaper.Rd
+cbc932856dc584b571a425fe4b7ec414 *man/hexList.Rd
+e674cd78f6a724d5613ddc81c6983b10 *man/hexMA.loess.Rd
+15c9da95418b954cc0feeec69eff71cb *man/hexTapply.Rd
+18c065f4f0c331f17604d467cf00b305 *man/hexVP-class.Rd
+9c7707d15c10f959d35a0714dc65b667 *man/hexVP.abline.Rd
+1f4b3a61121669b0bccb6fdc4e5cd836 *man/hexViewport.Rd
+92c69549ef7b876c66bd362e17216c44 *man/hexbin.Rd
+22b3b2d3c0f376d10a284f34eb647229 *man/hexbinplot.Rd
+37d121666c32d6396a680761b201162d *man/hexplom.Rd
+13241d553371e3923f6647b3a7deea77 *man/hexpolygon.Rd
+85e71d3e73900af44b7e88ead81c033c *man/hsmooth-methods.Rd
+7ea0b41a11cca81d2093012166c35101 *man/inout.hex.Rd
+fe9d76fede0a6c4727a6efb5c2e3c861 *man/list2hexList.Rd
+087875e158137bd1494533ffc2078ebd *man/old-classes.Rd
+6ed5394a980386786a41eaffd7dd5c8a *man/optShape.Rd
+9f23953a55209099110283ec98343438 *man/panel.hexboxplot.Rd
+3d36abbaab3ec18876e2288151da11f1 *man/panel.hexgrid.Rd
+d62970352d19f6785e76d6c68f3ba79e *man/panel.hexloess.Rd
+9da0d7245fb3f734cc0f07cb4f2aa123 *man/plotMAhex.Rd
+fc017f52b40dc804a41ea45305c840d8 *man/pushHexport.Rd
+febf2f7e1ad56316da2058e260732d7a *man/smooth.hexbin.Rd
+886e2efe62994815b8acfcc78c7ad81b *src/hbin.f
+470ef863da306fb9d0955b3cdb0b2ce0 *src/hcell.f
+f8fb4b9ec5a1dbc174102d40377ce885 *src/herode.f
+719cbe239d3f98da12bd7f489ab6c197 *src/hsm.f
+ddcf0653ed6863dd0260e1f58349356a *tests/hdiffplot.R
+66fb0e8391d2b94fbdb2633ac4d70e21 *tests/hdiffplot.Rout.save
+efe67770786c28cc2bfceef357376f7a *tests/hray.R
+24021c6251d46ad71065e3705e04479d *tests/hray.Rout.save
+6dca74e0501c54cede56d657a1c0c632 *tests/large.R
+98321f01b4ed346aa059aec1aa3c637a *tests/large.Rout.save
+f94ffad94528308a3483bf6f4088fa70 *tests/viewp-ex.R
+53478aa4cafb6fb935b12b7c982a667d *tests/viewp-ex.Rout.save
+d6c9a9e05a1165a6e0da8b309303082b *vignettes/hexagon_binning.Rnw
diff --git a/NAMESPACE b/NAMESPACE
new file mode 100644
index 0000000..152789f
--- /dev/null
+++ b/NAMESPACE
@@ -0,0 +1,93 @@
+useDynLib(hexbin)
+
+
+import(methods)
+import(grid) ## too many things from grid
+import(lattice) ## too many things from lattice
+importFrom(graphics, plot, polygon)
+importFrom(grDevices, col2rgb, gray, grey, hsv, rgb, rgb2hsv,
+ xy.coords)
+importFrom(stats, coef, density, IQR, loess, loess.control, median,
+ predict, update)
+importFrom(utils, modifyList, str)
+
+
+## Generics and functions defined in this package
+export(
+ "erode",
+ "erode.hexbin",
+ "getHMedian",
+## document those; the method aliases are there:
+## "getFig", "getMargins", "getPlt", "getXscale", "getYscale",
+ "gplot.hexbin",
+ "grid.hexagons",
+ "grid.hexlegend",
+ "hboxplot",
+ "hcell2xy",
+ "hexbin",
+ "hexcoords",
+ "hexList",
+ "hexpolygon",
+ "hexViewport",
+ "hexVP.abline",
+ "plotMAhex",
+ "hexVP.loess",
+ "hexMA.loess",
+ "hsmooth",
+ "list2hexList",
+ "pushHexport",
+ "smooth.hexbin",
+ "hdiffplot", # but not all the helpers in ./R/hdiffplot.R
+ ## Stuff in hexutils
+ "hcell2xyInt",
+ "hgridcent",
+ "hexGraphPaper",
+ "hexTapply",
+ "optShape",
+ "inout.hex",
+ ## color stuff
+ "BTC", "BTY", "LinGray", "LinOCS", "heat.ob", "magent","plinrain",
+
+ ## Lattice stuff:
+
+ ## high-level functions
+ "hexbinplot", "hexplom",
+
+ ## panel functions
+ "panel.hexbinplot", "panel.hexplom", "panel.hexboxplot",
+ "panel.hexgrid","panel.hexloess",
+
+ ## utilities
+ "hexlegendGrob")
+
+
+## S3 methods for lattice-type functions
+
+S3method("hexbinplot", "formula")
+S3method("hexplom", "formula")
+S3method("hexplom", "matrix")
+S3method("hexplom", "data.frame")
+
+
+
+exportClasses("hexbin",
+ "erodebin",
+ "smoothbin",
+ "hexVP",
+ # could/should we keep this 'private' (?) :
+ "integer or NULL",
+ "hexbinList"
+ )
+
+exportMethods(
+ "erode",
+## undocumented: "getFig", "getMargins", "getPlt", "getXscale", "getYscale",
+ "hsmooth",
+
+ "plot",
+ "summary",
+ "show",
+ "coerce"
+ )
+
+
diff --git a/R/BTC.R b/R/BTC.R
new file mode 100644
index 0000000..5457fd8
--- /dev/null
+++ b/R/BTC.R
@@ -0,0 +1,268 @@
+BTC <- function(n, beg = 1, end = 256)
+{
+ if(beg < 1 || end < 1 || beg > 256 || end > 256)
+ stop("`beg' and `end' must be numbers in the interval [1,256]")
+
+ M <- rbind(c(0,0,0),
+ c(0,0,40),
+ c(0,4,56),
+ c(0,9,61),
+ c(0,12,64),
+ c(0,14,66),
+ c(0,17,69),
+ c(0,20,73),
+ c(0,22,74),
+ c(0,25,78),
+ c(0,27,79),
+ c(0,30,83),
+ c(0,31,85),
+ c(0,33,86),
+ c(0,36,90),
+ c(0,38,91),
+ c(0,39,93),
+ c(0,41,95),
+ c(0,43,96),
+ c(0,46,100),
+ c(0,47,102),
+ c(0,49,103),
+ c(0,51,105),
+ c(0,52,107),
+ c(0,54,108),
+ c(0,55,110),
+ c(0,57,112),
+ c(0,57,112),
+ c(0,58,113),
+ c(0,60,115),
+ c(0,62,117),
+ c(0,63,119),
+ c(0,65,120),
+ c(0,66,122),
+ c(0,68,124),
+ c(0,70,125),
+ c(0,71,127),
+ c(0,73,129),
+ c(0,73,129),
+ c(0,74,130),
+ c(0,76,132),
+ c(0,78,134),
+ c(0,79,136),
+ c(0,81,137),
+ c(0,82,139),
+ c(0,84,141),
+ c(0,86,142),
+ c(0,87,144),
+ c(0,89,146),
+ c(0,90,147),
+ c(0,92,149),
+ c(0,94,151),
+ c(0,94,151),
+ c(0,95,153),
+ c(0,97,154),
+ c(0,98,156),
+ c(0,100,158),
+ c(0,102,159),
+ c(0,103,161),
+ c(0,105,163),
+ c(0,106,164),
+ c(0,108,166),
+ c(0,109,168),
+ c(0,111,170),
+ c(0,113,171),
+ c(0,114,173),
+ c(0,116,175),
+ c(0,117,176),
+ c(0,119,178),
+ c(0,121,180),
+ c(0,121,180),
+ c(0,122,181),
+ c(0,124,183),
+ c(0,125,185),
+ c(0,127,187),
+ c(0,129,188),
+ c(0,130,190),
+ c(0,132,192),
+ c(0,133,193),
+ c(0,135,195),
+ c(0,137,197),
+ c(0,138,198),
+ c(0,140,200),
+ c(0,141,202),
+ c(0,143,204),
+ c(0,143,204),
+ c(0,145,205),
+ c(0,146,207),
+ c(0,148,209),
+ c(0,149,210),
+ c(0,151,212),
+ c(0,153,214),
+ c(0,154,215),
+ c(0,156,217),
+ c(0,157,219),
+ c(0,159,221),
+ c(0,160,222),
+ c(0,160,222),
+ c(0,162,224),
+ c(0,164,226),
+ c(0,165,227),
+ c(0,167,229),
+ c(0,168,231),
+ c(0,170,232),
+ c(0,172,234),
+ c(0,173,236),
+ c(0,175,238),
+ c(0,175,238),
+ c(0,176,239),
+ c(0,178,241),
+ c(0,180,243),
+ c(0,181,244),
+ c(0,183,246),
+ c(2,184,248),
+ c(4,186,249),
+ c(4,186,249),
+ c(4,186,249),
+ c(6,188,251),
+ c(6,188,251),
+ c(9,189,253),
+ c(9,189,253),
+ c( 11,191,255),
+ c( 11,191,255),
+ c( 13,192,255),
+ c( 13,192,255),
+ c( 13,192,255),
+ c( 16,194,255),
+ c( 18,196,255),
+ c( 20,197,255),
+ c( 20,197,255),
+ c( 23,199,255),
+ c( 25,200,255),
+ c( 27,202,255),
+ c( 30,204,255),
+ c( 32,205,255),
+ c( 34,207,255),
+ c( 37,208,255),
+ c( 37,208,255),
+ c( 39,210,255),
+ c( 41,211,255),
+ c( 44,213,255),
+ c( 46,215,255),
+ c( 48,216,255),
+ c( 51,218,255),
+ c( 53,219,255),
+ c( 53,219,255),
+ c( 55,221,255),
+ c( 57,223,255),
+ c( 60,224,255),
+ c( 62,226,255),
+ c( 64,227,255),
+ c( 67,229,255),
+ c( 67,229,255),
+ c( 69,231,255),
+ c( 71,232,255),
+ c( 74,234,255),
+ c( 76,235,255),
+ c( 78,237,255),
+ c( 81,239,255),
+ c( 81,239,255),
+ c( 83,240,255),
+ c( 85,242,255),
+ c( 88,243,255),
+ c( 90,245,255),
+ c( 92,247,255),
+ c( 95,248,255),
+ c( 95,248,255),
+ c( 97,250,255),
+ c( 99,251,255),
+ c(102,253,255),
+ c(104,255,255),
+ c(106,255,255),
+ c(106,255,255),
+ c(108,255,255),
+ c(111,255,255),
+ c(113,255,255),
+ c(115,255,255),
+ c(115,255,255),
+ c(118,255,255),
+ c(120,255,255),
+ c(122,255,255),
+ c(122,255,255),
+ c(125,255,255),
+ c(127,255,255),
+ c(129,255,255),
+ c(129,255,255),
+ c(132,255,255),
+ c(134,255,255),
+ c(136,255,255),
+ c(136,255,255),
+ c(139,255,255),
+ c(141,255,255),
+ c(143,255,255),
+ c(143,255,255),
+ c(146,255,255),
+ c(148,255,255),
+ c(150,255,255),
+ c(150,255,255),
+ c(153,255,255),
+ c(155,255,255),
+ c(155,255,255),
+ c(157,255,255),
+ c(159,255,255),
+ c(159,255,255),
+ c(162,255,255),
+ c(164,255,255),
+ c(164,255,255),
+ c(166,255,255),
+ c(169,255,255),
+ c(171,255,255),
+ c(171,255,255),
+ c(173,255,255),
+ c(176,255,255),
+ c(176,255,255),
+ c(178,255,255),
+ c(180,255,255),
+ c(180,255,255),
+ c(183,255,255),
+ c(185,255,255),
+ c(185,255,255),
+ c(187,255,255),
+ c(190,255,255),
+ c(190,255,255),
+ c(192,255,255),
+ c(194,255,255),
+ c(197,255,255),
+ c(197,255,255),
+ c(199,255,255),
+ c(201,255,255),
+ c(204,255,255),
+ c(204,255,255),
+ c(206,255,255),
+ c(208,255,255),
+ c(210,255,255),
+ c(210,255,255),
+ c(213,255,255),
+ c(215,255,255),
+ c(217,255,255),
+ c(217,255,255),
+ c(220,255,255),
+ c(222,255,255),
+ c(224,255,255),
+ c(227,255,255),
+ c(229,255,255),
+ c(229,255,255),
+ c(231,255,255),
+ c(234,255,255),
+ c(236,255,255),
+ c(238,255,255),
+ c(241,255,255),
+ c(243,255,255),
+ c(243,255,255),
+ c(245,255,255),
+ c(248,255,255),
+ c(250,255,255),
+ c(255,255,255))[ round(seq(beg,end, length = n)), ]
+
+ rgb(M[,1]/255,
+ M[,2]/255,
+ M[,3]/255)
+}
+
+
diff --git a/R/BTY.R b/R/BTY.R
new file mode 100644
index 0000000..954c2a3
--- /dev/null
+++ b/R/BTY.R
@@ -0,0 +1,266 @@
+BTY <- function(n, beg = 1, end = 256)
+{
+ if(beg < 1 || end < 1 || beg > 256 || end > 256)
+ stop("`beg' and `end' must be numbers in the interval [1,256]")
+
+ M <- rbind(c(7,7,254),
+ c(23,23,252),
+ c(30,30,250),
+ c(36,36,248),
+ c(40,40,247),
+ c(44,44,245),
+ c(47,47,243),
+ c(50,50,242),
+ c(52,52,240),
+ c(55,55,239),
+ c(57,57,238),
+ c(59,59,236),
+ c(61,61,235),
+ c(63,63,234),
+ c(65,65,233),
+ c(66,66,231),
+ c(68,68,230),
+ c(69,69,229),
+ c(71,71,228),
+ c(72,72,227),
+ c(74,74,226),
+ c(75,75,225),
+ c(76,76,225),
+ c(78,78,224),
+ c(79,79,223),
+ c(80,80,222),
+ c(81,81,221),
+ c(82,82,221),
+ c(84,84,220),
+ c(85,85,219),
+ c(86,86,218),
+ c(87,87,218),
+ c(88,88,217),
+ c(89,89,216),
+ c(90,90,216),
+ c(91,91,215),
+ c(92,92,214),
+ c(93,93,214),
+ c(94,94,213),
+ c(95,95,213),
+ c(96,96,212),
+ c(97,97,212),
+ c(98,98,211),
+ c(98,98,210),
+ c(99,99,210),
+ c(100,100,209),
+ c(101,101,209),
+ c(102,102,208),
+ c(103,103,208),
+ c(104,104,208),
+ c(105,105,207),
+ c(105,105,207),
+ c(106,106,206),
+ c(107,107,206),
+ c(108,108,205),
+ c(109,109,205),
+ c(110,110,204),
+ c(110,110,204),
+ c(111,111,204),
+ c(112,112,203),
+ c(113,113,203),
+ c(114,114,202),
+ c(114,114,202),
+ c(115,115,202),
+ c(116,116,201),
+ c(117,117,201),
+ c(118,118,200),
+ c(118,118,200),
+ c(119,119,200),
+ c(120,120,199),
+ c(121,121,199),
+ c(121,121,199),
+ c(122,122,198),
+ c(123,123,198),
+ c(124,124,198),
+ c(124,124,197),
+ c(125,125,197),
+ c(126,126,197),
+ c(127,127,196),
+ c(128,128,196),
+ c(128,128,195),
+ c(129,129,195),
+ c(130,130,195),
+ c(130,130,194),
+ c(131,131,194),
+ c(132,132,194),
+ c(133,133,193),
+ c(133,133,193),
+ c(134,134,193),
+ c(135,135,192),
+ c(136,136,192),
+ c(136,136,192),
+ c(137,137,191),
+ c(138,138,191),
+ c(139,139,191),
+ c(139,139,190),
+ c(140,140,190),
+ c(141,141,190),
+ c(142,142,189),
+ c(142,142,189),
+ c(143,143,189),
+ c(144,144,188),
+ c(144,144,188),
+ c(145,145,188),
+ c(146,146,187),
+ c(147,147,187),
+ c(147,147,187),
+ c(148,148,186),
+ c(149,149,186),
+ c(149,149,186),
+ c(150,150,185),
+ c(151,151,185),
+ c(152,152,185),
+ c(152,152,184),
+ c(153,153,184),
+ c(154,154,184),
+ c(154,154,183),
+ c(155,155,183),
+ c(156,156,182),
+ c(157,157,182),
+ c(157,157,182),
+ c(158,158,181),
+ c(159,159,181),
+ c(159,159,181),
+ c(160,160,180),
+ c(161,161,180),
+ c(162,162,180),
+ c(162,162,179),
+ c(163,163,179),
+ c(164,164,178),
+ c(164,164,178),
+ c(165,165,178),
+ c(166,166,177),
+ c(167,167,177),
+ c(167,167,176),
+ c(168,168,176),
+ c(169,169,176),
+ c(169,169,175),
+ c(170,170,175),
+ c(171,171,174),
+ c(172,172,174),
+ c(172,172,173),
+ c(173,173,173),
+ c(174,174,173),
+ c(174,174,172),
+ c(175,175,172),
+ c(176,176,171),
+ c(177,177,171),
+ c(177,177,170),
+ c(178,178,170),
+ c(179,179,169),
+ c(179,179,169),
+ c(180,180,168),
+ c(181,181,168),
+ c(181,181,167),
+ c(182,182,167),
+ c(183,183,166),
+ c(184,184,166),
+ c(184,184,165),
+ c(185,185,165),
+ c(186,186,164),
+ c(186,186,164),
+ c(187,187,163),
+ c(188,188,163),
+ c(189,189,162),
+ c(189,189,162),
+ c(190,190,161),
+ c(191,191,161),
+ c(191,191,160),
+ c(192,192,159),
+ c(193,193,159),
+ c(194,194,158),
+ c(194,194,158),
+ c(195,195,157),
+ c(196,196,157),
+ c(196,196,156),
+ c(197,197,155),
+ c(198,198,155),
+ c(199,199,154),
+ c(199,199,153),
+ c(200,200,153),
+ c(201,201,152),
+ c(201,201,151),
+ c(202,202,151),
+ c(203,203,150),
+ c(204,204,149),
+ c(204,204,149),
+ c(205,205,148),
+ c(206,206,147),
+ c(206,206,146),
+ c(207,207,146),
+ c(208,208,145),
+ c(209,209,144),
+ c(209,209,143),
+ c(210,210,143),
+ c(211,211,142),
+ c(211,211,141),
+ c(212,212,140),
+ c(213,213,139),
+ c(214,214,138),
+ c(214,214,138),
+ c(215,215,137),
+ c(216,216,136),
+ c(216,216,135),
+ c(217,217,134),
+ c(218,218,133),
+ c(219,219,132),
+ c(219,219,131),
+ c(220,220,130),
+ c(221,221,129),
+ c(221,221,128),
+ c(222,222,127),
+ c(223,223,126),
+ c(224,224,125),
+ c(224,224,124),
+ c(225,225,123),
+ c(226,226,122),
+ c(226,226,121),
+ c(227,227,119),
+ c(228,228,118),
+ c(229,229,117),
+ c(229,229,116),
+ c(230,230,114),
+ c(231,231,113),
+ c(232,232,112),
+ c(232,232,110),
+ c(233,233,109),
+ c(234,234,107),
+ c(234,234,106),
+ c(235,235,104),
+ c(236,236,103),
+ c(237,237,101),
+ c(237,237,100),
+ c(238,238,98),
+ c(239,239,96),
+ c(239,239,94),
+ c(240,240,92),
+ c(241,241,91),
+ c(242,242,89),
+ c(242,242,86),
+ c(243,243,84),
+ c(244,244,82),
+ c(245,245,80),
+ c(245,245,77),
+ c(246,246,74),
+ c(247,247,72),
+ c(247,247,69),
+ c(248,248,65),
+ c(249,249,62),
+ c(250,250,58),
+ c(250,250,54),
+ c(251,251,49),
+ c(252,252,44),
+ c(253,253,37),
+ c(253,253,28),
+ c(254,254,13))[ round(seq(beg,end, length = n)), ]
+
+ rgb(M[,1]/255,
+ M[,2]/255,
+ M[,3]/255)
+}
diff --git a/R/HO.R b/R/HO.R
new file mode 100644
index 0000000..c73a470
--- /dev/null
+++ b/R/HO.R
@@ -0,0 +1,267 @@
+heat.ob <- function(n,beg = 1,end = 256)
+{
+ if(beg < 1 || end < 1 || beg > 256 || end > 256)
+ stop("`beg' and `end' must be numbers in the interval [1,256]")
+
+ M <- rbind(c(0, 0, 0),
+ c(35, 0, 0),
+ c(52, 0, 0),
+ c(60, 0, 0),
+ c(63, 1, 0),
+ c(64, 2, 0),
+ c(68, 5, 0),
+ c(69, 6, 0),
+ c(72, 8, 0),
+ c(74,10, 0),
+ c(77,12, 0),
+ c(78,14, 0),
+ c(81,16, 0),
+ c(83,17, 0),
+ c(85,19, 0),
+ c(86,20, 0),
+ c(89,22, 0),
+ c(91,24, 0),
+ c(92,25, 0),
+ c(94,26, 0),
+ c(95,28, 0),
+ c(98,30, 0),
+ c(100,31, 0),
+ c(102,33, 0),
+ c(103,34, 0),
+ c(105,35, 0),
+ c(106,36, 0),
+ c(108,38, 0),
+ c(109,39, 0),
+ c(111,40, 0),
+ c(112,42, 0),
+ c(114,43, 0),
+ c(115,44, 0),
+ c(117,45, 0),
+ c(119,47, 0),
+ c(119,47, 0),
+ c(120,48, 0),
+ c(122,49, 0),
+ c(123,51, 0),
+ c(125,52, 0),
+ c(125,52, 0),
+ c(126,53, 0),
+ c(128,54, 0),
+ c(129,56, 0),
+ c(129,56, 0),
+ c(131,57, 0),
+ c(132,58, 0),
+ c(134,59, 0),
+ c(134,59, 0),
+ c(136,61, 0),
+ c(137,62, 0),
+ c(137,62, 0),
+ c(139,63, 0),
+ c(139,63, 0),
+ c(140,65, 0),
+ c(142,66, 0),
+ c(142,66, 0),
+ c(143,67, 0),
+ c(143,67, 0),
+ c(145,68, 0),
+ c(145,68, 0),
+ c(146,70, 0),
+ c(146,70, 0),
+ c(148,71, 0),
+ c(148,71, 0),
+ c(149,72, 0),
+ c(149,72, 0),
+ c(151,73, 0),
+ c(151,73, 0),
+ c(153,75, 0),
+ c(153,75, 0),
+ c(154,76, 0),
+ c(154,76, 0),
+ c(154,76, 0),
+ c(156,77, 0),
+ c(156,77, 0),
+ c(157,79, 0),
+ c(157,79, 0),
+ c(159,80, 0),
+ c(159,80, 0),
+ c(159,80, 0),
+ c(160,81, 0),
+ c(160,81, 0),
+ c(162,82, 0),
+ c(162,82, 0),
+ c(163,84, 0),
+ c(163,84, 0),
+ c(165,85, 0),
+ c(165,85, 0),
+ c(166,86, 0),
+ c(166,86, 0),
+ c(166,86, 0),
+ c(168,87, 0),
+ c(168,87, 0),
+ c(170,89, 0),
+ c(170,89, 0),
+ c(171,90, 0),
+ c(171,90, 0),
+ c(173,91, 0),
+ c(173,91, 0),
+ c(174,93, 0),
+ c(174,93, 0),
+ c(176,94, 0),
+ c(176,94, 0),
+ c(177,95, 0),
+ c(177,95, 0),
+ c(179,96, 0),
+ c(179,96, 0),
+ c(180,98, 0),
+ c(182,99, 0),
+ c(182,99, 0),
+ c(183,100, 0),
+ c(183,100, 0),
+ c(185,102, 0),
+ c(185,102, 0),
+ c(187,103, 0),
+ c(187,103, 0),
+ c(188,104, 0),
+ c(188,104, 0),
+ c(190,105, 0),
+ c(191,107, 0),
+ c(191,107, 0),
+ c(193,108, 0),
+ c(193,108, 0),
+ c(194,109, 0),
+ c(196,110, 0),
+ c(196,110, 0),
+ c(197,112, 0),
+ c(197,112, 0),
+ c(199,113, 0),
+ c(200,114, 0),
+ c(200,114, 0),
+ c(202,116, 0),
+ c(202,116, 0),
+ c(204,117, 0),
+ c(205,118, 0),
+ c(205,118, 0),
+ c(207,119, 0),
+ c(208,121, 0),
+ c(208,121, 0),
+ c(210,122, 0),
+ c(211,123, 0),
+ c(211,123, 0),
+ c(213,124, 0),
+ c(214,126, 0),
+ c(214,126, 0),
+ c(216,127, 0),
+ c(217,128, 0),
+ c(217,128, 0),
+ c(219,130, 0),
+ c(221,131, 0),
+ c(221,131, 0),
+ c(222,132, 0),
+ c(224,133, 0),
+ c(224,133, 0),
+ c(225,135, 0),
+ c(227,136, 0),
+ c(227,136, 0),
+ c(228,137, 0),
+ c(230,138, 0),
+ c(230,138, 0),
+ c(231,140, 0),
+ c(233,141, 0),
+ c(233,141, 0),
+ c(234,142, 0),
+ c(236,144, 0),
+ c(236,144, 0),
+ c(238,145, 0),
+ c(239,146, 0),
+ c(241,147, 0),
+ c(241,147, 0),
+ c(242,149, 0),
+ c(244,150, 0),
+ c(244,150, 0),
+ c(245,151, 0),
+ c(247,153, 0),
+ c(247,153, 0),
+ c(248,154, 0),
+ c(250,155, 0),
+ c(251,156, 0),
+ c(251,156, 0),
+ c(253,158, 0),
+ c(255,159, 0),
+ c(255,159, 0),
+ c(255,160, 0),
+ c(255,161, 0),
+ c(255,163, 0),
+ c(255,163, 0),
+ c(255,164, 0),
+ c(255,165, 0),
+ c(255,167, 0),
+ c(255,167, 0),
+ c(255,168, 0),
+ c(255,169, 0),
+ c(255,169, 0),
+ c(255,170, 0),
+ c(255,172, 0),
+ c(255,173, 0),
+ c(255,173, 0),
+ c(255,174, 0),
+ c(255,175, 0),
+ c(255,177, 0),
+ c(255,178, 0),
+ c(255,179, 0),
+ c(255,181, 0),
+ c(255,181, 0),
+ c(255,182, 0),
+ c(255,183, 0),
+ c(255,184, 0),
+ c(255,187, 7),
+ c(255,188,10),
+ c(255,189,14),
+ c(255,191,18),
+ c(255,192,21),
+ c(255,193,25),
+ c(255,195,29),
+ c(255,197,36),
+ c(255,198,40),
+ c(255,200,43),
+ c(255,202,51),
+ c(255,204,54),
+ c(255,206,61),
+ c(255,207,65),
+ c(255,210,72),
+ c(255,211,76),
+ c(255,214,83),
+ c(255,216,91),
+ c(255,219,98),
+ c(255,221,105),
+ c(255,223,109),
+ c(255,225,116),
+ c(255,228,123),
+ c(255,232,134),
+ c(255,234,142),
+ c(255,237,149),
+ c(255,239,156),
+ c(255,240,160),
+ c(255,243,167),
+ c(255,246,174),
+ c(255,248,182),
+ c(255,249,185),
+ c(255,252,193),
+ c(255,253,196),
+ c(255,255,204),
+ c(255,255,207),
+ c(255,255,211),
+ c(255,255,218),
+ c(255,255,222),
+ c(255,255,225),
+ c(255,255,229),
+ c(255,255,233),
+ c(255,255,236),
+ c(255,255,240),
+ c(255,255,244),
+ c(255,255,247),
+ c(255,255,255))[ round(seq(beg,end,length = n)), ]
+
+ rgb(M[,1]/255,
+ M[,2]/255,
+ M[,3]/255)
+
+}
diff --git a/R/LINGRAY.R b/R/LINGRAY.R
new file mode 100644
index 0000000..a448734
--- /dev/null
+++ b/R/LINGRAY.R
@@ -0,0 +1,111 @@
+LinGray <- function(n,beg = 1,end = 92)
+{
+ if(beg < 1 || end < 1 || beg > 256 || end > 256)
+ stop("`beg' and `end' must be numbers in the interval [1,256]")
+
+ M <- rbind(c(0,0,0),
+ c(0,0,0),
+ c(1,1,1),
+ c(1,1,1),
+ c(2,2,2),
+ c(3,3,3),
+ c(4,4,4),
+ c(5,5,5),
+ c(6,6,6),
+ c(7,7,7),
+ c(8,8,8),
+ c(9,9,9),
+ c(10,10,10),
+ c(11,11,11),
+ c(12,12,12),
+ c(13,13,13),
+ c(14,14,14),
+ c(15,15,15),
+ c(16,16,16),
+ c(17,17,17),
+ c(18,18,18),
+ c(19,19,19),
+ c(20,20,20),
+ c(21,21,21),
+ c(22,22,22),
+ c(23,23,23),
+ c(24,24,24),
+ c(25,25,25),
+ c(26,26,26),
+ c(27,27,27),
+ c(28,28,28),
+ c(29,29,29),
+ c(30,30,30),
+ c(32,32,32),
+ c(34,34,34),
+ c(35,35,35),
+ c(37,37,37),
+ c(39,39,39),
+ c(41,41,41),
+ c(43,43,43),
+ c(45,45,45),
+ c(46,46,46),
+ c(47,47,47),
+ c(49,49,49),
+ c(51,51,51),
+ c(52,52,52),
+ c(54,54,54),
+ c(56,56,56),
+ c(59,59,59),
+ c(61,61,61),
+ c(64,64,64),
+ c(67,67,67),
+ c(69,69,69),
+ c(72,72,72),
+ c(75,75,75),
+ c(76,76,76),
+ c(78,78,78),
+ c(81,81,81),
+ c(84,84,84),
+ c(87,87,87),
+ c(91,91,91),
+ c(94,94,94),
+ c(97,97,97),
+ c(101,101,101),
+ c(104,104,104),
+ c(107,107,107),
+ c(108,108,108),
+ c(112,112,112),
+ c(116,116,116),
+ c(120,120,120),
+ c(124,124,124),
+ c(128,128,128),
+ c(132,132,132),
+ c(136,136,136),
+ c(141,141,141),
+ c(145,145,145),
+ c(147,147,147),
+ c(150,150,150),
+ c(154,154,154),
+ c(159,159,159),
+ c(164,164,164),
+ c(169,169,169),
+ c(174,174,174),
+ c(179,179,179),
+ c(185,185,185),
+ c(190,190,190),
+ c(195,195,195),
+ c(201,201,201),
+ c(207,207,207),
+ c(212,212,212),
+ c(216,216,216),
+ c(218,218,218),
+ c(224,224,224),
+ c(226,226,226),
+ c(230,230,230),
+ c(237,237,237),
+ c(243,243,243),
+ c(245,245,245),
+ c(252,252,252),
+ c(255,255,255),
+ c(255,255,255))[round(seq(beg,end,length = n)), ]
+
+ rgb(M[,1]/255,
+ M[,2]/255,
+ M[,3]/255)
+}
diff --git a/R/LOCS.R b/R/LOCS.R
new file mode 100644
index 0000000..fd73ae7
--- /dev/null
+++ b/R/LOCS.R
@@ -0,0 +1,266 @@
+LinOCS <- function(n,beg = 1,end = 256)
+{
+ if(beg < 1 || end < 1 || beg > 256 || end > 256)
+ stop("`beg' and `end' must be numbers in the interval [1,256]")
+
+ M <- rbind(c(0,0,0),
+ c(0,0,0),
+ c(0,0,0),
+ c(1,0,0),
+ c(2,0,0),
+ c(2,0,0),
+ c(3,0,0),
+ c(3,0,0),
+ c(4,0,0),
+ c(5,0,0),
+ c(5,0,0),
+ c(6,0,0),
+ c(7,0,0),
+ c(7,0,0),
+ c(8,0,0),
+ c(9,0,0),
+ c(9,0,0),
+ c(10,0,0),
+ c(11,0,0),
+ c(12,0,0),
+ c(13,0,0),
+ c(14,0,0),
+ c(15,0,0),
+ c(16,0,0),
+ c(17,0,0),
+ c(18,0,0),
+ c(19,0,0),
+ c(20,0,0),
+ c(21,0,0),
+ c(22,0,0),
+ c(23,0,0),
+ c(25,0,0),
+ c(26,0,0),
+ c(27,0,0),
+ c(28,0,0),
+ c(30,0,0),
+ c(31,0,0),
+ c(33,0,0),
+ c(34,0,0),
+ c(35,0,0),
+ c(37,0,0),
+ c(39,0,0),
+ c(40,0,0),
+ c(43,0,0),
+ c(45,0,0),
+ c(46,0,0),
+ c(49,0,0),
+ c(51,0,0),
+ c(53,0,0),
+ c(54,0,0),
+ c(56,0,0),
+ c(58,0,0),
+ c(60,0,0),
+ c(62,0,0),
+ c(64,0,0),
+ c(67,0,0),
+ c(69,0,0),
+ c(71,0,0),
+ c(74,0,0),
+ c(76,0,0),
+ c(80,0,0),
+ c(81,0,0),
+ c(84,0,0),
+ c(86,0,0),
+ c(89,0,0),
+ c(92,0,0),
+ c(94,0,0),
+ c(97,0,0),
+ c(100,0,0),
+ c(103,0,0),
+ c(106,0,0),
+ c(109,0,0),
+ c(112,0,0),
+ c(115,0,0),
+ c(117,0,0),
+ c(122,0,0),
+ c(126,0,0),
+ c(128,0,0),
+ c(131,0,0),
+ c(135,0,0),
+ c(135,0,0),
+ c(135,1,0),
+ c(135,2,0),
+ c(135,3,0),
+ c(135,4,0),
+ c(135,6,0),
+ c(135,6,0),
+ c(135,8,0),
+ c(135,9,0),
+ c(135,10,0),
+ c(135,11,0),
+ c(135,13,0),
+ c(135,13,0),
+ c(135,15,0),
+ c(135,17,0),
+ c(135,17,0),
+ c(135,19,0),
+ c(135,21,0),
+ c(135,22,0),
+ c(135,23,0),
+ c(135,25,0),
+ c(135,26,0),
+ c(135,27,0),
+ c(135,29,0),
+ c(135,31,0),
+ c(135,32,0),
+ c(135,33,0),
+ c(135,35,0),
+ c(135,36,0),
+ c(135,38,0),
+ c(135,40,0),
+ c(135,42,0),
+ c(135,44,0),
+ c(135,46,0),
+ c(135,47,0),
+ c(135,49,0),
+ c(135,51,0),
+ c(135,52,0),
+ c(135,54,0),
+ c(135,56,0),
+ c(135,57,0),
+ c(135,59,0),
+ c(135,62,0),
+ c(135,63,0),
+ c(135,65,0),
+ c(135,67,0),
+ c(135,69,0),
+ c(135,72,0),
+ c(135,73,0),
+ c(135,76,0),
+ c(135,78,0),
+ c(135,80,0),
+ c(135,82,0),
+ c(135,84,0),
+ c(135,87,0),
+ c(135,88,0),
+ c(135,90,0),
+ c(135,93,0),
+ c(135,95,0),
+ c(135,98,0),
+ c(135,101,0),
+ c(135,103,0),
+ c(135,106,0),
+ c(135,107,0),
+ c(135,110,0),
+ c(135,113,0),
+ c(135,115,0),
+ c(135,118,0),
+ c(135,121,0),
+ c(135,124,0),
+ c(135,127,0),
+ c(135,129,0),
+ c(135,133,0),
+ c(135,135,0),
+ c(135,138,0),
+ c(135,141,0),
+ c(135,144,0),
+ c(135,148,0),
+ c(135,150,0),
+ c(135,155,0),
+ c(135,157,0),
+ c(135,160,0),
+ c(135,163,0),
+ c(135,166,0),
+ c(135,170,0),
+ c(135,174,0),
+ c(135,177,0),
+ c(135,180,0),
+ c(135,184,0),
+ c(135,188,0),
+ c(135,192,0),
+ c(135,195,0),
+ c(135,200,0),
+ c(135,203,0),
+ c(135,205,0),
+ c(135,210,0),
+ c(135,214,0),
+ c(135,218,0),
+ c(135,222,0),
+ c(135,226,0),
+ c(135,231,0),
+ c(135,236,0),
+ c(135,239,0),
+ c(135,244,0),
+ c(135,249,0),
+ c(135,254,0),
+ c(135,255,1),
+ c(135,255,5),
+ c(135,255,10),
+ c(135,255,15),
+ c(135,255,20),
+ c(135,255,23),
+ c(135,255,28),
+ c(135,255,33),
+ c(135,255,38),
+ c(135,255,43),
+ c(135,255,45),
+ c(135,255,49),
+ c(135,255,54),
+ c(135,255,59),
+ c(135,255,65),
+ c(135,255,70),
+ c(135,255,74),
+ c(135,255,80),
+ c(135,255,84),
+ c(135,255,90),
+ c(135,255,95),
+ c(135,255,98),
+ c(135,255,104),
+ c(135,255,110),
+ c(135,255,116),
+ c(135,255,120),
+ c(135,255,125),
+ c(135,255,131),
+ c(135,255,137),
+ c(135,255,144),
+ c(135,255,149),
+ c(135,255,154),
+ c(135,255,158),
+ c(135,255,165),
+ c(135,255,172),
+ c(135,255,179),
+ c(135,255,186),
+ c(135,255,191),
+ c(135,255,198),
+ c(135,255,203),
+ c(135,255,211),
+ c(135,255,216),
+ c(135,255,224),
+ c(135,255,232),
+ c(135,255,240),
+ c(135,255,248),
+ c(135,255,254),
+ c(135,255,255),
+ c(140,255,255),
+ c(146,255,255),
+ c(153,255,255),
+ c(156,255,255),
+ c(161,255,255),
+ c(168,255,255),
+ c(172,255,255),
+ c(177,255,255),
+ c(182,255,255),
+ c(189,255,255),
+ c(192,255,255),
+ c(199,255,255),
+ c(204,255,255),
+ c(210,255,255),
+ c(215,255,255),
+ c(220,255,255),
+ c(225,255,255),
+ c(232,255,255),
+ c(236,255,255),
+ c(240,255,255),
+ c(248,255,255),
+ c(255,255,255))[ round(seq(beg,end,length = n)), ]
+
+ rgb(M[,1]/255,
+ M[,2]/255,
+ M[,3]/255)
+}
diff --git a/R/MAG.R b/R/MAG.R
new file mode 100644
index 0000000..5721749
--- /dev/null
+++ b/R/MAG.R
@@ -0,0 +1,266 @@
+magent <- function(n, beg = 1, end = 256)
+{
+ if(beg < 1 || end < 1 || beg > 256 || end > 256)
+ stop("`beg' and `end' must be numbers in the interval [1,256]")
+
+ M <- rbind(c(0, 0, 0),
+ c( 40, 0, 0),
+ c( 56, 0, 4),
+ c( 61, 0, 9),
+ c( 64, 0, 12),
+ c( 66, 0, 14),
+ c( 69, 0, 17),
+ c( 73, 0, 20),
+ c( 74, 0, 22),
+ c( 78, 0, 25),
+ c( 79, 0, 27),
+ c( 83, 0, 30),
+ c( 85, 0, 31),
+ c( 86, 0, 33),
+ c( 90, 0, 36),
+ c( 91, 0, 38),
+ c( 93, 0, 39),
+ c( 95, 0, 41),
+ c( 96, 0, 43),
+ c(100, 0, 46),
+ c(102, 0, 47),
+ c(103, 0, 49),
+ c(105, 0, 51),
+ c(107, 0, 52),
+ c(108, 0, 54),
+ c(110, 0, 55),
+ c(112, 0, 57),
+ c(112, 0, 57),
+ c(113, 0, 58),
+ c(115, 0, 60),
+ c(117, 0, 62),
+ c(119, 0, 63),
+ c(120, 0, 65),
+ c(122, 0, 66),
+ c(124, 0, 68),
+ c(125, 0, 70),
+ c(127, 0, 71),
+ c(129, 0, 73),
+ c(129, 0, 73),
+ c(130, 0, 74),
+ c(132, 0, 76),
+ c(134, 0, 78),
+ c(136, 0, 79),
+ c(137, 0, 81),
+ c(139, 0, 82),
+ c(141, 0, 84),
+ c(142, 0, 86),
+ c(144, 0, 87),
+ c(146, 0, 89),
+ c(147, 0, 90),
+ c(149, 0, 92),
+ c(151, 0, 94),
+ c(151, 0, 94),
+ c(153, 0, 95),
+ c(154, 0, 97),
+ c(156, 0, 98),
+ c(158, 0,100),
+ c(159, 0,102),
+ c(161, 0,103),
+ c(163, 0,105),
+ c(164, 0,106),
+ c(166, 0,108),
+ c(168, 0,109),
+ c(170, 0,111),
+ c(171, 0,113),
+ c(173, 0,114),
+ c(175, 0,116),
+ c(176, 0,117),
+ c(178, 0,119),
+ c(180, 0,121),
+ c(180, 0,121),
+ c(181, 0,122),
+ c(183, 0,124),
+ c(185, 0,125),
+ c(187, 0,127),
+ c(188, 0,129),
+ c(190, 0,130),
+ c(192, 0,132),
+ c(193, 0,133),
+ c(195, 0,135),
+ c(197, 0,137),
+ c(198, 0,138),
+ c(200, 0,140),
+ c(202, 0,141),
+ c(204, 0,143),
+ c(204, 0,143),
+ c(205, 0,145),
+ c(207, 0,146),
+ c(209, 0,148),
+ c(210, 0,149),
+ c(212, 0,151),
+ c(214, 0,153),
+ c(215, 0,154),
+ c(217, 0,156),
+ c(219, 0,157),
+ c(221, 0,159),
+ c(222, 0,160),
+ c(222, 0,160),
+ c(224, 0,162),
+ c(226, 0,164),
+ c(227, 0,165),
+ c(229, 0,167),
+ c(231, 0,168),
+ c(232, 0,170),
+ c(234, 0,172),
+ c(236, 0,173),
+ c(238, 0,175),
+ c(238, 0,175),
+ c(239, 0,176),
+ c(241, 0,178),
+ c(243, 0,180),
+ c(244, 0,181),
+ c(246, 0,183),
+ c(248, 2,184),
+ c(249, 4,186),
+ c(249, 4,186),
+ c(249, 4,186),
+ c(251, 6,188),
+ c(251, 6,188),
+ c(253, 9,189),
+ c(253, 9,189),
+ c(255, 11,191),
+ c(255, 11,191),
+ c(255, 13,192),
+ c(255, 13,192),
+ c(255, 13,192),
+ c(255, 16,194),
+ c(255, 18,196),
+ c(255, 20,197),
+ c(255, 20,197),
+ c(255, 23,199),
+ c(255, 25,200),
+ c(255, 27,202),
+ c(255, 30,204),
+ c(255, 32,205),
+ c(255, 34,207),
+ c(255, 37,208),
+ c(255, 37,208),
+ c(255, 39,210),
+ c(255, 41,211),
+ c(255, 44,213),
+ c(255, 46,215),
+ c(255, 48,216),
+ c(255, 51,218),
+ c(255, 53,219),
+ c(255, 53,219),
+ c(255, 55,221),
+ c(255, 57,223),
+ c(255, 60,224),
+ c(255, 62,226),
+ c(255, 64,227),
+ c(255, 67,229),
+ c(255, 67,229),
+ c(255, 69,231),
+ c(255, 71,232),
+ c(255, 74,234),
+ c(255, 76,235),
+ c(255, 78,237),
+ c(255, 81,239),
+ c(255, 81,239),
+ c(255, 83,240),
+ c(255, 85,242),
+ c(255, 88,243),
+ c(255, 90,245),
+ c(255, 92,247),
+ c(255, 95,248),
+ c(255, 95,248),
+ c(255, 97,250),
+ c(255, 99,251),
+ c(255,102,253),
+ c(255,104,255),
+ c(255,106,255),
+ c(255,106,255),
+ c(255,108,255),
+ c(255,111,255),
+ c(255,113,255),
+ c(255,115,255),
+ c(255,115,255),
+ c(255,118,255),
+ c(255,120,255),
+ c(255,122,255),
+ c(255,122,255),
+ c(255,125,255),
+ c(255,127,255),
+ c(255,129,255),
+ c(255,129,255),
+ c(255,132,255),
+ c(255,134,255),
+ c(255,136,255),
+ c(255,136,255),
+ c(255,139,255),
+ c(255,141,255),
+ c(255,143,255),
+ c(255,143,255),
+ c(255,146,255),
+ c(255,148,255),
+ c(255,150,255),
+ c(255,150,255),
+ c(255,153,255),
+ c(255,155,255),
+ c(255,155,255),
+ c(255,157,255),
+ c(255,159,255),
+ c(255,159,255),
+ c(255,162,255),
+ c(255,164,255),
+ c(255,164,255),
+ c(255,166,255),
+ c(255,169,255),
+ c(255,171,255),
+ c(255,171,255),
+ c(255,173,255),
+ c(255,176,255),
+ c(255,176,255),
+ c(255,178,255),
+ c(255,180,255),
+ c(255,180,255),
+ c(255,183,255),
+ c(255,185,255),
+ c(255,185,255),
+ c(255,187,255),
+ c(255,190,255),
+ c(255,190,255),
+ c(255,192,255),
+ c(255,194,255),
+ c(255,197,255),
+ c(255,197,255),
+ c(255,199,255),
+ c(255,201,255),
+ c(255,204,255),
+ c(255,204,255),
+ c(255,206,255),
+ c(255,208,255),
+ c(255,210,255),
+ c(255,210,255),
+ c(255,213,255),
+ c(255,215,255),
+ c(255,217,255),
+ c(255,217,255),
+ c(255,220,255),
+ c(255,222,255),
+ c(255,224,255),
+ c(255,227,255),
+ c(255,229,255),
+ c(255,229,255),
+ c(255,231,255),
+ c(255,234,255),
+ c(255,236,255),
+ c(255,238,255),
+ c(255,241,255),
+ c(255,243,255),
+ c(255,243,255),
+ c(255,245,255),
+ c(255,248,255),
+ c(255,250,255),
+ c(255,255,255)) [ round(seq(beg,end,length = n)), ]
+
+ rgb(M[,1]/255,
+ M[,2]/255,
+ M[,3]/255)
+}
diff --git a/R/RB.R b/R/RB.R
new file mode 100644
index 0000000..6e92aaa
--- /dev/null
+++ b/R/RB.R
@@ -0,0 +1,266 @@
+plinrain <- function(n, beg = 1, end = 256)
+{
+ if(beg < 1 || end < 1 || beg > 256 || end > 256)
+ stop("`beg' and `end' must be numbers in the interval [1,256]")
+
+ M <- rbind(c( 0, 0, 0),
+ c( 45, 0, 36),
+ c( 56, 0, 46),
+ c( 60, 0, 49),
+ c( 67, 0, 54),
+ c( 70, 0, 59),
+ c( 71, 0, 61),
+ c( 75, 0, 68),
+ c( 74, 0, 73),
+ c( 74, 0, 77),
+ c( 73, 0, 81),
+ c( 71, 0, 87),
+ c( 69, 1, 90),
+ c( 68, 2, 94),
+ c( 66, 3, 97),
+ c( 63, 6,102),
+ c( 61, 7,106),
+ c( 58, 10,109),
+ c( 56, 12,113),
+ c( 53, 15,116),
+ c( 48, 18,119),
+ c( 47, 20,121),
+ c( 44, 23,124),
+ c( 41, 27,128),
+ c( 40, 28,129),
+ c( 37, 32,132),
+ c( 34, 36,134),
+ c( 29, 43,137),
+ c( 25, 52,138),
+ c( 24, 57,139),
+ c( 24, 62,141),
+ c( 24, 64,142),
+ c( 23, 65,142),
+ c( 23, 69,143),
+ c( 23, 71,142),
+ c( 23, 71,142),
+ c( 23, 73,142),
+ c( 23, 75,142),
+ c( 23, 75,142),
+ c( 23, 78,142),
+ c( 23, 80,142),
+ c( 23, 80,142),
+ c( 23, 82,141),
+ c( 23, 85,141),
+ c( 23, 85,141),
+ c( 23, 87,140),
+ c( 23, 87,140),
+ c( 24, 90,140),
+ c( 24, 90,140),
+ c( 24, 93,139),
+ c( 24, 93,139),
+ c( 24, 93,139),
+ c( 24, 93,139),
+ c( 24, 97,139),
+ c( 24, 97,139),
+ c( 25,101,138),
+ c( 25,101,138),
+ c( 25,104,137),
+ c( 25,104,137),
+ c( 25,104,137),
+ c( 26,108,137),
+ c( 26,108,137),
+ c( 27,111,136),
+ c( 27,111,136),
+ c( 27,111,136),
+ c( 27,115,135),
+ c( 27,115,135),
+ c( 28,118,134),
+ c( 28,118,134),
+ c( 29,122,133),
+ c( 29,122,133),
+ c( 29,122,133),
+ c( 29,122,133),
+ c( 29,125,132),
+ c( 29,125,132),
+ c( 30,128,131),
+ c( 30,128,131),
+ c( 31,131,130),
+ c( 31,131,130),
+ c( 31,131,130),
+ c( 32,134,128),
+ c( 32,134,128),
+ c( 33,137,127),
+ c( 33,137,127),
+ c( 33,137,127),
+ c( 34,140,125),
+ c( 34,140,125),
+ c( 35,142,123),
+ c( 35,142,123),
+ c( 36,145,121),
+ c( 36,145,121),
+ c( 36,145,121),
+ c( 37,147,118),
+ c( 37,147,118),
+ c( 38,150,116),
+ c( 38,150,116),
+ c( 40,152,113),
+ c( 40,152,113),
+ c( 41,154,111),
+ c( 41,154,111),
+ c( 42,156,108),
+ c( 42,156,108),
+ c( 43,158,106),
+ c( 43,158,106),
+ c( 43,158,106),
+ c( 45,160,104),
+ c( 45,160,104),
+ c( 46,162,101),
+ c( 46,162,101),
+ c( 48,164, 99),
+ c( 48,164, 99),
+ c( 50,166, 97),
+ c( 50,166, 97),
+ c( 51,168, 95),
+ c( 53,170, 93),
+ c( 53,170, 93),
+ c( 53,170, 93),
+ c( 55,172, 91),
+ c( 55,172, 91),
+ c( 57,174, 88),
+ c( 57,174, 88),
+ c( 59,175, 86),
+ c( 62,177, 84),
+ c( 64,178, 82),
+ c( 64,178, 82),
+ c( 67,180, 80),
+ c( 67,180, 80),
+ c( 69,181, 79),
+ c( 72,183, 77),
+ c( 72,183, 77),
+ c( 72,183, 77),
+ c( 75,184, 76),
+ c( 77,186, 74),
+ c( 80,187, 73),
+ c( 83,189, 72),
+ c( 87,190, 72),
+ c( 91,191, 71),
+ c( 95,192, 70),
+ c( 99,193, 70),
+ c(103,194, 70),
+ c(107,195, 70),
+ c(111,196, 70),
+ c(111,196, 70),
+ c(115,196, 70),
+ c(119,197, 70),
+ c(123,197, 70),
+ c(130,198, 71),
+ c(133,199, 71),
+ c(137,199, 72),
+ c(140,199, 72),
+ c(143,199, 73),
+ c(143,199, 73),
+ c(147,199, 73),
+ c(150,199, 74),
+ c(153,199, 74),
+ c(156,199, 75),
+ c(160,200, 76),
+ c(167,200, 78),
+ c(170,200, 79),
+ c(173,200, 79),
+ c(173,200, 79),
+ c(177,200, 80),
+ c(180,200, 81),
+ c(183,199, 82),
+ c(186,199, 82),
+ c(190,199, 83),
+ c(196,199, 85),
+ c(199,198, 85),
+ c(199,198, 85),
+ c(203,198, 86),
+ c(206,197, 87),
+ c(212,197, 89),
+ c(215,196, 90),
+ c(218,195, 91),
+ c(224,194, 94),
+ c(224,194, 94),
+ c(230,193, 96),
+ c(233,192, 98),
+ c(236,190,100),
+ c(238,189,104),
+ c(240,188,106),
+ c(240,188,106),
+ c(242,187,110),
+ c(244,185,114),
+ c(245,184,116),
+ c(247,183,120),
+ c(248,182,123),
+ c(248,182,123),
+ c(250,181,125),
+ c(251,180,128),
+ c(252,180,130),
+ c(253,180,133),
+ c(253,180,133),
+ c(254,180,134),
+ c(254,179,138),
+ c(255,179,142),
+ c(255,179,145),
+ c(255,179,145),
+ c(255,179,152),
+ c(255,180,161),
+ c(255,180,164),
+ c(255,180,167),
+ c(255,180,167),
+ c(255,181,169),
+ c(255,181,170),
+ c(255,182,173),
+ c(255,183,176),
+ c(255,183,176),
+ c(255,184,179),
+ c(255,185,179),
+ c(255,185,182),
+ c(255,186,182),
+ c(255,186,182),
+ c(255,187,185),
+ c(255,188,185),
+ c(255,189,188),
+ c(255,189,188),
+ c(255,190,188),
+ c(255,191,191),
+ c(255,192,191),
+ c(255,194,194),
+ c(255,194,194),
+ c(255,197,197),
+ c(255,198,198),
+ c(255,200,200),
+ c(255,201,201),
+ c(255,201,201),
+ c(255,202,202),
+ c(255,203,203),
+ c(255,205,205),
+ c(255,206,206),
+ c(255,206,206),
+ c(255,208,208),
+ c(255,209,209),
+ c(255,211,211),
+ c(255,215,215),
+ c(255,216,216),
+ c(255,216,216),
+ c(255,218,218),
+ c(255,219,219),
+ c(255,221,221),
+ c(255,223,223),
+ c(255,226,226),
+ c(255,228,228),
+ c(255,230,230),
+ c(255,230,230),
+ c(255,232,232),
+ c(255,235,235),
+ c(255,237,237),
+ c(255,240,240),
+ c(255,243,243),
+ c(255,246,246),
+ c(255,249,249),
+ c(255,251,251),
+ c(255,253,253),
+ c(255,255,255))[ round(seq(beg,end, length = n)), ]
+
+ rgb(M[,1]/255,
+ M[,2]/255,
+ M[,3]/255)
+}
diff --git a/R/grid.hexagons.R b/R/grid.hexagons.R
new file mode 100644
index 0000000..fcc45a2
--- /dev/null
+++ b/R/grid.hexagons.R
@@ -0,0 +1,366 @@
+
+hexcoords <- function(dx, dy = NULL, n = 1, sep = NULL)
+{
+ stopifnot(length(dx) == 1)
+ if(is.null(dy)) dy <- dx/sqrt(3)
+ if(is.null(sep))
+ list(x = rep.int(c(dx, dx, 0, -dx, -dx, 0), n),
+ y = rep.int(c(dy,-dy, -2*dy, -dy, dy, 2*dy), n),
+ no.sep = TRUE)
+ else
+ list(x = rep.int(c(dx, dx, 0, -dx, -dx, 0, sep), n),
+ y = rep.int(c(dy,-dy, -2*dy, -dy, dy, 2*dy, sep), n),
+ no.sep = FALSE)
+}
+
+hexpolygon <-
+function(x, y, hexC = hexcoords(dx, dy, n = 1), dx, dy=NULL,
+ fill = 1, border = 0, hUnit = "native", ...)
+{
+ ## Purpose: draw hexagon [grid.]polygon()'s around (x[i], y[i])_i
+ ## Author: Martin Maechler, Jul 2004; Nicholas for grid
+
+ n <- length(x)
+ stopifnot(length(y) == n)
+ stopifnot(is.list(hexC) && is.numeric(hexC$x) && is.numeric(hexC$y))
+ if(hexC$no.sep) {
+ n6 <- rep.int(6:6, n)
+ if(!is.null(hUnit)) {
+ grid.polygon(x = unit(rep.int(hexC$x, n) + rep.int(x, n6),hUnit),
+ y = unit(rep.int(hexC$y, n) + rep.int(y, n6),hUnit),
+ id.lengths = n6,
+ gp = gpar(col= border, fill= fill))
+ }
+ else {
+ grid.polygon(x = rep.int(hexC$x, n) + rep.int(x, n6),
+ y = rep.int(hexC$y, n) + rep.int(y, n6),
+ id.lengths = n6,
+ gp = gpar(col= border, fill= fill))
+ }
+ }
+ else{ ## traditional graphics polygons: must be closed explicitly (+ 1 pt)
+ n7 <- rep.int(7:7, n)
+ polygon(x = rep.int(hexC$x, n) + rep.int(x, n7),
+ y = rep.int(hexC$y, n) + rep.int(y, n7), ...)
+ }
+}
+
+grid.hexagons <-
+function(dat, style = c("colorscale", "centroids", "lattice",
+ "nested.lattice", "nested.centroids", "constant.col"),
+ use.count=TRUE, cell.at=NULL,
+ minarea = 0.05, maxarea = 0.8, check.erosion = TRUE,
+ mincnt = 1, maxcnt = max(dat at count), trans = NULL,
+ colorcut = seq(0, 1, length = 17),
+ density = NULL, border = NULL, pen = NULL,
+ colramp = function(n){ LinGray(n,beg = 90, end = 15) },
+ def.unit = "native",
+ verbose = getOption("verbose"))
+{
+ ## Warning: presumes the plot has the right shape and scales
+ ## See plot.hexbin()
+ ## Arguments:
+ ## dat = hexbin object
+ ## style = type of plotting
+ ## 'centroids' = symbol area is a function of the count,
+ ## approximate location near cell center of
+ ## mass without overplotting
+ ## 'lattice' = symbol area is a function of the count,
+ ## plot at lattice points
+ ## 'colorscale' = gray scale plot,
+ ## color number determined by
+ ## transformation and colorcut,
+ ## area = full hexagons.
+ ## 'nested.lattice'= plots two hexagons
+ ## background hexagon
+ ## area=full size
+ ## color number by count in powers of 10 starting at pen 2
+ ## foreground hexagon
+ ## area by log10(cnt)-floor(log10(cnt))
+ ## color number by count in powers of 10 starting at pen 12
+ ## 'nested.centroids' = like nested.lattice
+ ## but counts < 10 are plotted
+ ##
+ ## minarea = minimum symbol area as fraction of the binning cell
+ ## maxarea = maximum symbol area as fraction of the binning cell
+ ## mincnt = minimum count accepted in plot
+ ## maxcnt = maximum count accepted in plot
+ ## trans = a transformation scaling counts into [0,1] to be applied
+ ## to the counts for options 'centroids','lattice','colorscale':
+ ## default=(cnt-mincnt)/(maxcnt-mincnt)
+ ## colorcut= breaks for translating values between 0 and 1 into
+ ## color classes. Default= seq(0,1,17),
+ ## density = for hexagon graph paper
+ ## border plot the border of the hexagon, use TRUE for
+ ## hexagon graph paper
+ ## Symbol size encoding:
+ ## Area= minarea + scaled.count*(maxarea-minarea)
+ ## When maxarea==1 and scaled.count==1, the hexagon cell
+ ## is completely filled.
+ ##
+ ## If small hexagons are hard to see increase minarea.
+ ## For gray scale encoding
+ ## Uses the counts scaled into [0,1]
+ ## Default gray cutpoints seq(0,1,17) yields 16 color classes
+ ## The color number for the first class starts at 2.
+ ## motif coding: black 15 white puts the first of the
+ ## color class above the background black
+ ## The function subtracts 1.e-6 from the lower cutpoint to include
+ ## the boundary
+ ## For nested scaling see the code
+ ## Count scaling alternatives
+ ##
+ ## log 10 and Poisson transformations
+ ## trans <- function(cnt) log10(cnt)
+ ## min inv <- function(y) 10^y
+ ##
+ ## trans <- function(cnt) sqrt(4*cnt+2)
+ ## inv <- function(y) (y^2-2)/4
+ ## Perceptual considerations.
+ ## Visual response to relative symbol area is not linear and varies from
+ ## person to person. A fractional power transformation
+ ## to make the interpretation nearly linear for more people
+ ## might be considered. With areas bounded between minarea
+ ## and 1 the situation is complicated.
+ ##
+ ## The local background influences color interpretation.
+ ## Having defined color breaks to focus attention on
+ ## specific countours can help.
+ ##
+ ## Plotting the symbols near the center of mass is not only more accurate,
+ ## it helps to reduce the visual dominance of the lattice structure. Of
+ ## course higher resolution binning reduces the possible distance between
+ ## the center of mass for a bin and the bin center. When symbols
+ ## nearly fill their bin, the plot appears to vibrate. This can be
+ ## partially controlled by reducing maxarea or by reducing
+ ## contrast.
+
+
+ ##____________________Initial checks_______________________
+ if(!is(dat,"hexbin"))
+ stop("first argument must be a hexbin object")
+ style <- match.arg(style) # so user can abbreviate
+ if(minarea <= 0)
+ stop("hexagons cannot have a zero area, change minarea")
+ if(maxarea > 1)
+ warning("maxarea > 1, hexagons may overplot")
+ ##_______________ Collect computing constants______________
+
+ if(use.count){
+ cnt <- dat at count
+ }
+ else{
+ cnt <- cell.at
+ if(is.null(cnt)){
+ if(is.null(dat at cAtt)) stop("Cell attribute cAtt is null")
+ else cnt <- dat at cAtt
+ }
+ }
+ xbins <- dat at xbins
+ shape <- dat at shape
+ tmp <- hcell2xy(dat, check.erosion = check.erosion)
+ good <- mincnt <= cnt & cnt <= maxcnt
+ xnew <- tmp$x[good]
+ ynew <- tmp$y[good]
+ cnt <- cnt[good]
+ sx <- xbins/diff(dat at xbnds)
+ sy <- (xbins * shape)/diff(dat at ybnds)
+
+ ##___________Transform Counts to Radius_____________________
+ switch(style,
+ "centroids" = ,
+ "lattice" = ,
+ "constant.col" =,
+ "colorscale" = {
+ if(is.null(trans)) {
+ if( min(cnt,na.rm=TRUE)< 0){
+ pcnt<- cnt + min(cnt)
+ rcnt <- {
+ if(maxcnt == mincnt) rep.int(1, length(cnt))
+ else (pcnt - mincnt)/(maxcnt - mincnt)
+ }
+ }
+ else rcnt <- {
+ if(maxcnt == mincnt) rep.int(1, length(cnt))
+ else (cnt - mincnt)/(maxcnt - mincnt)
+ }
+ }
+ else {
+ rcnt <- (trans(cnt) - trans(mincnt)) /
+ (trans(maxcnt) - trans(mincnt))
+ if(any(is.na(rcnt)))
+ stop("bad count transformation")
+ }
+ area <- minarea + rcnt * (maxarea - minarea)
+ },
+ "nested.lattice" = ,
+ "nested.centroids" = {
+ diffarea <- maxarea - minarea
+ step <- 10^floor(log10(cnt))
+ f <- (cnt/step - 1)/9
+ area <- minarea + f * diffarea
+ area <- pmax(area, minarea)
+ }
+ )
+ area <- pmin(area, maxarea)
+ radius <- sqrt(area)
+
+ ##______________Set Colors_____________________________
+ switch(style,
+ "centroids" = ,
+ "constant.col" = ,
+ "lattice" = {
+ if(length(pen)!= length(cnt)){
+ if(is.null(pen)) pen <- rep.int(1, length(cnt))
+ ##else if(length(pen)== length(cnt)) break
+ else if(length(pen)== 1) pen <- rep.int(pen,length(cnt))
+ else stop("'pen' has wrong length")
+ }
+ },
+ "nested.lattice" = ,
+ "nested.centroids" = {
+ if(!is.null(pen) && length(dim(pen)) == 2) {
+ dp <- dim(pen)
+ lgMcnt <- ceiling(log10(max(cnt)))
+ if(dp[1] != length(cnt) && dp[1] != lgMcnt ) {
+ stop ("pen is not of right dimension")
+ }
+ if( dp[1] == lgMcnt ) {
+ ind <- ceiling(log10(dat at count)) ## DS: 'dat' was 'bin' (??)
+ ind[ind == 0] <- 1
+ pen <- pen[ind,]
+ }
+ ##else break
+ }
+ else {
+ pen <- floor(log10(cnt)) + 2
+ pen <- cbind(pen, pen+10)
+ }
+ },
+ "colorscale" = {
+ ## MM: Following is quite different from bin2d's
+ nc <- length(colorcut)
+ if(colorcut[1] > colorcut[nc]){
+ colorcut[1] <- colorcut[1] + 1e-06
+ colorcut[nc] <- colorcut[nc] - 1e-06
+ } else {
+ colorcut[1] <- colorcut[1] - 1e-06
+ colorcut[nc] <- colorcut[nc] + 1e-06
+ }
+ colgrp <- cut(rcnt, colorcut,labels = FALSE)
+ if(any(is.na(colgrp))) colgrp <- ifelse(is.na(colgrp),0,colgrp)
+ ##NL: colramp must be a function accepting an integer n
+ ## and returning n colors
+ clrs <- colramp(length(colorcut) - 1)
+ pen <- clrs[colgrp]
+ }
+ )
+
+ ##__________________ Construct a hexagon___________________
+ ## The inner and outer radius for hexagon in the scaled plot
+ inner <- 0.5
+ outer <- (2 * inner)/sqrt(3)
+ ## Now construct a point up hexagon symbol in data units
+ dx <- inner/sx
+ dy <- outer/(2 * sy)
+ rad <- sqrt(dx^2 + dy^2)
+ hexC <- hexcoords(dx, dy, sep=NULL)
+ ##_______________ Full Cell Plotting_____________________
+ switch(style,
+ "constant.col" = ,
+ "colorscale" = {
+ hexpolygon(xnew, ynew, hexC,
+ density = density, fill = pen,
+ border = if(!is.null(border)) border else pen)
+
+ ## and that's been all for these styles
+ return(invisible(paste("done", sQuote(style))))
+ },
+ "nested.lattice" = ,
+ "nested.centroids" = {
+ hexpolygon(xnew, ynew, hexC,
+ density = density,
+ fill = if (is.null(border) || border) 1 else pen[,1],
+ border = pen[,1])
+ }
+ )
+
+ ##__________________ Symbol Center adjustments_______________
+ if(style == "centroids" || style == "nested.centroids") {
+ xcm <- dat at xcm[good]
+ ycm <- dat at ycm[good]
+ ## Store 12 angles around a circle and the replicate the first
+ ## The actual length for these vectors is determined by using
+ ## factor use below
+ k <- sqrt(3)/2
+ cosx <- c(1, k, .5, 0, -.5, -k, -1, -k, -.5, 0, .5, k, 1)/sx
+ siny <- c(0, .5, k, 1, k, .5, 0, -.5, -k, -1, -k, -.5, 0)/sy
+ ## Compute distances for differences after scaling into
+ ## [0,size] x [0,aspect*size]
+ ## Then there are size hexagons on the x axis
+ dx <- sx * (xcm - xnew)
+ dy <- sy * (ycm - ynew)
+ dlen <- sqrt(dx^2 + dy^2)
+ ## Find the closest approximating direction of the 12 vectors above
+ cost <- ifelse(dlen > 0, dx/dlen, 0)
+ tk <- (6 * acos(cost))/pi
+ tk <- round(ifelse(dy < 0, 12 - tk, tk)) + 1
+ ## Select the available length for the approximating vector
+ hrad <- ifelse(tk %% 2 == 1, inner, outer)
+ ## Rad is either an inner or outer approximating radius.
+ ## If dlen + hrad*radius <= hrad, move the center dlen units.
+ ## Else move as much of dlen as possible without overplotting.
+ fr <- pmin(hrad * (1 - radius), dlen) # Compute the symbol centers
+ ## fr is the distance for the plot [0,xbins] x [0,aspect*xbins]
+
+ ## cosx and siny give the x and y components of this distance
+ ## in data units
+ xnew <- xnew + fr * cosx[tk]
+ ynew <- ynew + fr * siny[tk]
+ }
+ ## ________________Sized Hexagon Plotting__________________
+ ## scale the symbol by radius and add to the new center
+ n <- length(radius)
+ if(verbose)
+ cat('length = ',length(pen),"\n", 'pen = ', pen+1,"\n")
+ ##switch(style,
+ ## centroids = ,
+ ## lattice = {if(is.null(pen))pen <- rep.int(1, n)
+ ## else pen <- rep.int(pen, n)},
+ ## nested.lattice = ,
+ ## nested.centroids ={
+ ## if(
+ ## pen[,2] <- pen[,1] + 10
+ ## } )
+
+ ## grid.polygon() closes automatically: now '6' where we had '7':
+ n6 <- rep.int(6:6, n)
+ pltx <- rep.int(hexC$x, n) * rep.int(radius, n6) + rep.int(xnew, n6)
+ plty <- rep.int(hexC$y, n) * rep.int(radius, n6) + rep.int(ynew, n6)
+ switch(style,
+ "centroids" = ,
+ "lattice" = {
+ grid.polygon(pltx, plty, default.units=def.unit, id=NULL,
+ ## density = density,
+ id.lengths= n6,
+ gp=gpar(fill = pen, col = border))
+ },
+ "nested.lattice" = ,
+ "nested.centroids" = {
+ grid.polygon(pltx, plty, default.units=def.unit, id=NULL,
+ id.lengths= n6,
+ gp=gpar(fill = pen[,2],
+ ## density = density,
+ col=if(!is.null(border)) border else pen[,2]))
+
+ })
+
+}
+
+if(FALSE){ ## considering 'hexagons' object
+ setMethod("hexagons", signature(dat="hexbin"), grid.hexagons)
+
+ erode.hexagons <- function(ebin,pen="black",border="red"){
+ print("Blank for now")
+ }
+}
diff --git a/R/grid.hexlegend.R b/R/grid.hexlegend.R
new file mode 100644
index 0000000..2692a31
--- /dev/null
+++ b/R/grid.hexlegend.R
@@ -0,0 +1,157 @@
+grid.hexlegend <-
+function(legend, ysize, lcex, inner,
+ style = "colorscale",
+ minarea = 0.05, maxarea = 0.8, mincnt = 1, maxcnt, trans = NULL,
+ inv = NULL, colorcut, density = NULL, border = NULL, pen = NULL,
+ colramp = function(n) { LinGray(n,beg = 90,end = 15) },
+ leg.unit="native")
+{
+ ## the formal arg matching should happen
+ style <- match.arg(style, eval(formals(grid.hexagons)[["style"]]))
+
+ if (style %in% c("centroids", "lattice", "colorscale")) {
+ ## _______________tranformations_______________________
+ if(is.null(trans)) {
+ sc <- maxcnt - mincnt
+ bnds <- round(mincnt + sc * colorcut)
+ }
+
+ else {
+ if(!is.function(trans) && !is.function(inv))
+ stop("'trans' and 'inv' must both be functions if 'trans' is not NULL")
+ con <- trans(mincnt)
+ sc <- trans(maxcnt) - con
+ bnds <- round(inv(con + sc * colorcut))
+ }
+ }
+
+ if(style == "colorscale") { ## use own 'inner'
+ n <- length(bnds)
+ spacing <- ysize/(n + 3)
+ inner <- min(legend/3.5, (sqrt(3) * spacing)/2)
+ }
+ dx <- inner/2
+ dy <- dx/sqrt(3)
+ hexC <- hexcoords(dx, dy, n = 1,sep=NULL)
+
+ ## _______________Plotting______________________________
+ switch(style,
+ "colorscale" = {
+ midx <- legend/3
+ textx <- (2 * legend)/3
+ tx <- hexC$x + midx
+ pen <- colramp(n)
+ for(i in seq(length = n-1)) {
+ grid.polygon(tx,hexC$y + i * spacing,
+ default.units=leg.unit,id=NULL,id.lengths=6,
+ gp=gpar(fill = pen[i], col = border))
+ grid.text(as.character(bnds[i]), textx, (i - 0.5) * spacing,
+ default.units=leg.unit, gp=gpar(cex = lcex))
+ }
+ grid.text(as.character(bnds[n]), textx, (n - 0.5) * spacing,
+ default.units=leg.unit, gp=gpar(cex = lcex))
+ grid.text("Counts", legend/2, (n + 1.5) * spacing,
+ default.units=leg.unit, gp=gpar(cex = 1.7 * lcex))
+ },
+
+ "centroids" = ,
+ "lattice" = {
+ ## NL Solved hex overlap problem on legend
+ ## Need to tackle too many categories
+ radius <- sqrt(minarea + (maxarea - minarea) * colorcut)
+ n <- length(radius)
+ shift <- c(0, 2*dy*radius)
+ shift <- shift[1:n] + shift[2:(n+1)]
+ #labht <- max(strheight(as.character(bnds), cex = lcex))
+ labht <- convertY(unit(get.gpar(names = "fontsize")[[1]]*lcex,
+ "points"),"native",valueOnly = TRUE)
+ shift <- pmax(labht, shift)
+ six <- rep.int(6:6, n)
+ xmid <- legend/3
+ inc <- ysize/(n+3)
+ if(inc > max(shift)) y <- inc * 1:n
+ else {
+ y <- cumsum(shift)
+ extra.slop <- (n * inc) - y[n] # FIXME? y[n] == sum(shift)
+ shift[-1] <- shift[-1] + extra.slop/(n-1)
+ y <- cumsum(shift)
+ ## (y+(1/n)*extra.slop)-y[1]
+ ## delta <- max(log(shift))-min(log(shift))
+ ## fudge <- extra.slop*(diff(log(shift))/delta)
+ ## y<- c(y[1], y[-1]+ fudge )
+ }
+ textx <- rep.int((2 * legend)/3, n)
+ ## ____________________plotting______________________
+ if(is.null(pen)) pen <- 1
+ if(is.null(border)) border <- pen
+ grid.polygon(x = rep.int(hexC$x,n)*
+ rep.int(radius, six) + rep.int(xmid, 6 * n),
+ y = rep.int(hexC$y,n)*
+ rep.int(radius, six) + rep.int(y, six),
+ default.units=leg.unit, id=NULL,
+ id.lengths=rep.int(6,n),
+ gp=gpar(fill = pen, col = border))
+
+ grid.text(as.character(bnds), textx, y,
+ default.units=leg.unit, gp=gpar(cex = lcex))
+ grid.text("Counts", legend/2, (n + 2) * inc,
+ default.units=leg.unit, gp=gpar(cex =1.7 * lcex))
+ },
+
+ "nested.lattice" = ,
+ "nested.centroids" = {
+ ## _____________x scaling_____________________________
+ numb <- cut(floor(legend/inner), breaks = c(-1, 0, 2,4))
+ ## Note: In old code
+ ## top breaks=c(-1,0,2,4,8), numb<- 5 and size=1:9
+ if(is.na(numb))
+ numb <- 4
+ switch(numb,
+ {warning("not enough space for legend"); return()},
+ size <- 5,
+ size <- c(1, 5, 9),
+ size <- c(1, 3, 5, 7, 9))
+ xmax <- length(size)
+ radius <- sqrt(minarea + (maxarea - minarea) * (size - 1)/9)
+ txt <- as.character(size)
+ ##___________________y scaling_____________________
+ lab <- c("Ones", "Tens", "Hundreds",
+ "Thousands", "10 Thousands", "100 Thousands",
+ "Millions", "10 Millions",
+ "100 Millions", "Billions")
+ power <- floor(log10(maxcnt)) + 1
+ yinc <- 16 * dy
+ if(ysize/power < yinc)
+ {warning("Not enough height for legend"); return()}
+ xmid <- legend/10
+ x <- inner * (1:xmax - (1 + xmax)/2) + xmid
+ n <- length(x)
+ tx <- rep.int(hexC$x, n)
+ ty <- rep.int(hexC$y, n)
+ six <- rep.int(6:6, n)
+ y <- rep.int(3 * dy - yinc, xmax)
+ ## ____________________plotting______________________
+ if(is.null(pen)) {
+ pen <- 1:power +1
+ pen <- cbind(pen, pen +10)
+ }
+ if(is.null(border)) border <- FALSE
+ for(i in 1:power) {
+ y <- y + yinc
+ hexpolygon(x, y, hexC,
+ col = pen[i,1], border = border)
+ grid.polygon(x= tx * rep.int(radius, six) + rep.int(x, six),
+ y= ty * rep.int(radius, six) + rep.int(y, six),
+ default.units=leg.unit, id=NULL,
+ id.lengths=rep(6,n),
+ gp=gpar(fill = pen[i,2], col = border))
+
+ grid.text(txt, x, y - 4.5 * dy,
+ default.units=leg.unit, gp=gpar(cex = lcex))
+ ##adj= 0.5, cex = lcex)
+ grid.text(lab[i], xmid, y[1] + 4.5 * dy,
+ default.units=leg.unit, gp=gpar(cex = 1.7*lcex))
+ ##adj= 0.5, cex = 1.7*lcex)
+ }
+ })## switch(style = *)
+}## hex.legend()
diff --git a/R/hbox.R b/R/hbox.R
new file mode 100644
index 0000000..46913e3
--- /dev/null
+++ b/R/hbox.R
@@ -0,0 +1,83 @@
+hboxplot <- function(bin, xbnds = NULL, ybnds = NULL,
+ density, border = c(0,grey(.7)),
+ pen = c(2, 3), unzoom = 1.1, clip="off", reshape = FALSE,
+ xlab = NULL, ylab = NULL, main = "")
+{
+
+ ##_______________ Collect computing constants______________
+
+ if(!is(bin,"hexbin"))
+ stop("first argument must be a hexbin object")
+ h.xy <- hcell2xy(bin,check.erosion=TRUE)
+ ##___zoom in scaling with expanding to avoid hexagons outside plot frame___
+
+ if(is(bin,"erodebin")) {
+ h.xy$x <- h.xy$x
+ h.xy$y <- h.xy$y
+ nxbnds <- if(is.null(xbnds)) range(h.xy$x) else xbnds
+ nybnds <- if(is.null(ybnds)) range(h.xy$y) else ybnds
+ ratiox <- diff(nxbnds)/diff(bin at xbnds)
+ ratioy <- diff(nybnds)/diff(bin at ybnds)
+
+ ratio <- max(ratioy, ratiox)
+ nxbnds <- mean(nxbnds) + c(-1,1)*(unzoom * ratio * diff(bin at xbnds))/2
+ nybnds <- mean(nybnds) + c(-1,1)*(unzoom * ratio * diff(bin at ybnds))/2
+ }
+ else {
+ nxbnds <- if(is.null(xbnds)) bin at xbnds else xbnds
+ nybnds <- if(is.null(ybnds)) bin at ybnds else ybnds
+ }
+ margins <- unit(0.1 + c(5,4,4,3),"lines")
+ plot.vp <- hexViewport(bin, xbnds = nxbnds, ybnds = nybnds,
+ mar=margins, newpage = TRUE)
+ pushHexport(plot.vp)
+ grid.rect()
+ grid.xaxis()
+ grid.yaxis()
+ ## xlab, ylab, main :
+ if(is.null(xlab)) xlab <- bin at xlab
+ if(is.null(ylab)) ylab <- bin at ylab
+ if(nchar(xlab) > 0)
+ grid.text(xlab, y = unit(-2, "lines"), gp= gpar(fontsize= 16))
+ if(nchar(ylab) > 0)
+ grid.text(ylab, x = unit(-2, "lines"), gp= gpar(fontsize= 16), rot = 90)
+ if(nchar(main) > 0)
+ grid.text(main, y = unit(1, "npc") + unit(1.5, "lines"),
+ gp = gpar(fontsize = 18))
+ if(clip=="on") {
+ popViewport()
+ pushHexport(plot.vp, clip="on")
+ }
+
+ cnt <- if(is(bin,"erodebin")) bin at count[bin at eroded] else bin at count
+
+ xbins <- bin at xbins
+ shape <- bin at shape
+ xnew <- h.xy$x
+ ynew <- h.xy$y
+
+ ##__________________ Construct a hexagon___________________
+ dx <- (0.5 * diff(bin at xbnds))/xbins
+ dy <- (0.5 * diff(bin at ybnds))/(xbins * shape * sqrt(3))
+ hexC <- hexcoords(dx, dy, sep = NULL)
+
+ ##_______________ Full Cell Plotting_____________________
+ hexpolygon(xnew, ynew, hexC, density = density,
+ fill = pen[2], border = border[2])
+
+ ##______________Plotting median___________________________
+
+ if(!is(bin,"erodebin")) {
+ ## No warning here, allow non-erode above! warning("No erode component")
+ }
+ else {
+ med <- which.max(bin at erode)
+ xnew <- xnew[med]
+ ynew <- ynew[med]
+ hexpolygon(xnew, ynew, hexC, density = density,
+ fill = pen[1], border = border[1])
+ }
+ popViewport()
+ invisible(plot.vp)
+
+}# hboxplot()
diff --git a/R/hdiffplot.R b/R/hdiffplot.R
new file mode 100644
index 0000000..8dcdca4
--- /dev/null
+++ b/R/hdiffplot.R
@@ -0,0 +1,331 @@
+
+### FIXME: Need to check for bin erosion
+### or fix hcell2xy so that it checks for bin erosion.
+### --- Fixed hcell2xy, probably should do the same to other accessor functions
+### NL
+
+get.xrange <- function(xy.lst, xbnds)
+{
+ range(unlist(lapply(xy.lst,
+ function(xy, bnd)
+ xy$x[(xy$x < max(bnd)) & (xy$x > min(bnd))],
+ xbnds)))
+}
+
+get.yrange <- function(xy.lst, ybnds)
+{
+ range(unlist(lapply(xy.lst,
+ function(xy, bnd)
+ xy$y[(xy$y < max(bnd)) & (xy$y > min(bnd))],
+ ybnds)))
+}
+
+make.bnds <- function(binlst, xy.lst, xbnds = NULL, ybnds = NULL)
+{
+ if(inherits(binlst,"hexbinList")) binlst <- binlst at hbins
+ if(is.null(xbnds)) xbnds <- binlst[[1]]@xbnds
+ if(is.null(ybnds)) ybnds <- binlst[[1]]@ybnds
+
+ nxbnds <- get.xrange(xy.lst, xbnds)
+ nybnds <- get.yrange(xy.lst, ybnds)
+
+ list(xbnds = xbnds, ybnds = ybnds, nxbnds = nxbnds, nybnds = nybnds)
+}
+
+all.intersect <- function(binlist)
+{
+ ## This will not work if all the grids are not the same
+ ## Will have to rethink this if we move to non-aligned
+ ## hexagon bins. NL
+ if(inherits(binlist,"hexbinList")) binlist <- binlist at hbins
+ ans <- matrix(FALSE, nrow = binlist[[1]]@dimen[1]*binlist[[1]]@dimen[2],
+ ncol = length(binlist))
+ for(i in 1:length(binlist)) {
+ if(is(binlist[[i]], "erodebin"))
+ ans[binlist[[i]]@cell[binlist[[i]]@eroded], i] <- TRUE
+ else ans[binlist[[i]]@cell, i] <- TRUE
+ }
+ ans
+}
+
+## colordist <- function() {
+## }
+
+## MM: FIXME : `` get(where) '' is a kludge!
+# EJP: outcomment, seems obsolete?
+#mixcolors <- function (alpha, color1, where = class(color1))
+#{
+# alpha <- as.numeric(alpha)
+# c1 <- coords(as(color1, where))
+# na <- length(alpha)
+# n1 <- nrow(c1)
+# if(na == 1)
+# alpha <- rep(alpha, n1)
+# stopifnot(sum(alpha) == 1)
+# get(where)(t(apply(c1, 2, function(cols, alpha) alpha%*%cols, alpha)))
+#
+#}
+
+mixcolors2 <- function (colors, alpha, where="hsv")
+{
+ # colors: an n x 3 matrix of colors
+ # alpha: an n x 1 vector of color mixing coefficents
+ # sum(alpha)==1 should be a restriction?
+ # where: the color space to mix in (not implemented yet)
+ # The reurn value is a single hex color forming the mixture
+ # This function is purely linear mixing, nolinear mixing
+ # would be quite interesting since the colorspaces are not really
+ # linear, ie mixing alonga manifold in LUV space.
+ alpha <- as.numeric(alpha)
+ na <- length(alpha)
+ n1 <- nrow(colors)
+ if (n1 < 2) {
+ warning("need more than two colors to mix")
+ colors
+ }
+ if(na == 1)
+ alpha <- rep(alpha, n1)
+ stopifnot(abs(sum(alpha)-1) <= 0.01)
+ #colors <- convertColor(colors,from="sRGB",to="Lab",scale.in=1)
+ mix <- t(apply(colors, 2, function(cols, alpha) alpha%*%cols, alpha))
+ #convertColor(mix,from="hsv",to="hex",scale.out=1,clip=TRUE)
+ hsv(mix[1],mix[2],mix[3])
+}
+
+hdiffplot <-
+ function(bin1, bin2 = NULL, xbnds = NULL, ybnds = NULL,
+ focus = NULL,
+ col.control = list(medhex = "white", med.bord = "black",
+ focus = NULL, focus.border = NULL,
+ back.col = "grey"),
+ arrows = TRUE, size = unit(0.1, "inches"), lwd = 2,
+ eps = 1e-6, unzoom = 1.08, clip ="off", xlab = "", ylab = "",
+ main = deparse(mycall), ...)
+{
+ ## Arguments:
+ ## bin1 : hexagon bin object or a list of bin objects
+ ## bin2 : hexagon bin object or NULL
+ ## bin objects must have the same plotting bounds and shape
+ ## border : plot the border of the hexagon, use TRUE for
+ ## hexagon graph paper
+
+ ## Having all the same parameters ensures that all hexbin
+ ## objects have the same hexagon grid, and there will be no
+ ## problems intersecting them. When we have a suitable solution to
+ ## the hexagon interpolation/intersection problem this will be relaxed.
+ fixx <- xbnds
+ fixy <- ybnds
+
+ if(!inherits(bin1,"hexbinList")){
+ if(is.null(bin2) & is.list(bin1)) {
+ bin1 <- as(bin1,"hexbinList")
+ }
+ else if(is.null(bin2) & (!is.list(bin1)))
+ stop(" need at least 2 hex bin objects, or a hexbinList")
+ else {
+ if(bin1 at shape != bin2 at shape)
+ stop("bin objects must have same shape parameter")
+ if(all(bin1 at xbnds == bin2 at xbnds) & all(bin1 at ybnds == bin2 at ybnds))
+ equal.bounds <- TRUE
+ else stop("Bin objects need the same xbnds and ybnds")
+ if(bin1 at xbins != bin2 at xbins)
+ stop("Bin objects need the same number of bins")
+ nhb <- 2
+ ## Need to make a binlist class, then can do as(bin1, bin2, "binlist")
+ ## or something similar (NL)
+ bin1 <- list(bin1 = bin1, bin2 = bin2)
+ bin1 <- as(bin1,"hexbinList")
+ }
+ }
+ mycall <- sys.call()
+ if(length(mycall) >= 4) {
+ mycall[4] <- as.call(quote(.....()))
+ if(length(mycall) > 4) mycall <- mycall[1:4]
+ }
+ if(is.null(focus)) focus <- 1:bin1 at n
+ ##_______________ Collect computing constants______________
+ tmph.xy <- lapply(bin1 at hbins, hcell2xy, check.erosion = TRUE)
+
+ ## Check for erode bins
+ eroded <- unlist(lapply(bin1 at hbins, is, "erodebin"))
+ shape <- bin1 at Shape
+ xbins <- bin1 at Xbins
+ bnds <- make.bnds(bin1 at hbins, tmph.xy, xbnds = fixx, ybnds = fixy)
+ ratiox <- diff(bnds$nxbnds)/diff(bnds$xbnds)
+ ratioy <- diff(bnds$nybnds)/diff(bnds$ybnds)
+ ratio <- max(ratioy, ratiox)
+
+ nxbnds <- mean(bnds$nxbnds) + c(-1, 1)*(unzoom * ratio * diff(bnds$xbnds))/2
+ nybnds <- mean(bnds$nybnds) + c(-1, 1)*(unzoom * ratio * diff(bnds$ybnds))/2
+
+ ##__________________ Construct plot region___________________
+ hvp <- hexViewport(bin1 at hbins[[1]], xbnds = nxbnds, ybnds = nybnds,
+ newpage = TRUE)
+ pushHexport(hvp)
+ grid.rect()
+ grid.xaxis()
+ grid.yaxis()
+ if(nchar(xlab) > 0)
+ grid.text(xlab, y = unit(-2, "lines"), gp = gpar(fontsize = 16))
+ if(nchar(ylab) > 0)
+ grid.text(ylab, x = unit(-2, "lines"), gp = gpar(fontsize = 16), rot = 90)
+ if(sum(nchar(main)) > 0)
+ grid.text(main, y = unit(1, "npc") + unit(1.5, "lines"),
+ gp = gpar(fontsize = 18))
+
+ if(clip=='on'){
+ popViewport()
+ pushHexport(hvp,clip="on")
+ }
+ ##__________________ Construct hexagon___________________
+ dx <- (0.5 * diff(bin1 at Xbnds))/xbins
+ dy <- (0.5 * diff(bin1 at Ybnds))/(xbins * shape * sqrt(3))
+ hexC <- hexcoords(dx = dx, dy = dy)
+
+ ##__________________ Set up intersections and colors___________________
+ if(length(focus) < bin1 at n) {
+ bin1 at hbins <- c(bin1 at hbins[focus], bin1 at hbins[-focus])
+ bin1 at Bnames <- c(bin1 at Bnames[focus], bin1 at Bnames[-focus])
+ }
+ cell.stat <- all.intersect(bin1 at hbins)
+ cell.stat.n <- apply(cell.stat, 1, sum)
+ i.depth <- max(cell.stat.n)
+
+### I will do this as a recursive function once I get
+### The colors worked out! In fact for more than three
+### bin objects there is no other way to do this but recursively!!!
+### NL. -- Well this solution is like recursion :)
+ diff.cols <- vector(mode = "list", length = i.depth)
+ levcells <- which(cell.stat.n == 1)
+ whichbin <- apply(cell.stat[levcells, ], 1, which)
+
+ ## Set all the focal colors for the unique bin cells
+ ## if not specified make them equally spaced on the color wheel
+ ## with high saturation and set the background bins to gray
+ nfcol <- length(focus)
+ nhb <- bin1 at n
+ nbcol <- nhb-nfcol
+ fills <-
+ if(is.null(col.control$focus)) {
+ if(nbcol > 0)
+ matrix(c(seq(0, 360, length = nfcol+1)[1:nfcol]/360, rep(0, nbcol),
+ rep(1, nfcol), rep(0, nbcol),rep(1, nfcol), rep(.9, nbcol)),
+ ncol = 3)
+ ## V = c(rep(1, nfcol), seq(.9, .1, length=nbcol))
+
+ else #matrix(c(seq(0, 360, length = nhb+1), s=1, v=1)[1:nfcol]
+ matrix(c(seq(0, 360, length = nhb+1)/360,
+ rep(1,nhb+1),
+ rep(1,nhb+1)), ncol = 3)[1:nhb,]
+ }
+ else {
+ foc.col <- t(rgb2hsv(col2rgb(col.control$focus)))
+ if(nbcol > 0) {
+ bcol <- matrix(c(rep(0, 2*nbcol), rep(.9, nbcol)), ncol = 3)
+ rbind(foc.col, bcol)
+ }
+ else foc.col
+ }
+ colnames(fills) <- c("h","s","v")
+ diff.cols[[1]] <- list(fill = fills, border = gray(.8))
+
+ ##_______________ Full Cell Plotting for Unique Bin1 Cells_________________
+
+ if(length(levcells) > 0) {
+ for(i in unique(whichbin)) {
+ pcells <-
+ if(eroded[i])
+ bin1 at hbins[[i]]@cell[bin1 at hbins[[i]]@eroded]
+ else bin1 at hbins[[i]]@cell
+ pcells <- which(pcells %in% levcells[whichbin == i])
+ pfill <- diff.cols[[1]]$fill[i,]
+ pfill <- hsv(pfill[1],pfill[2],pfill[3])
+ hexpolygon(x = tmph.xy[[i]]$x[pcells],
+ y = tmph.xy[[i]]$y[pcells], hexC,
+ border = diff.cols[[1]]$border ,
+ fill = pfill)
+ }
+ }
+
+ ## Now do the intersections. All intersections are convex
+ ## combinations of the colors of the overlapping unique bins in
+ ## the CIEluv colorspace. so if the binlist is of length 2 and
+ ## the focal hbins are "blue" and "yellow" respectively the
+ ## intersection would be green. First I need to get this to work
+ ## and then I can think about how to override this with an option
+ ## in color.control. -NL
+
+ if(i.depth > 1) {
+ for(dl in 2:(i.depth)) {
+ levcells <- which(cell.stat.n == dl)
+ if(length(levcells) == 0) next
+
+ whichbin <- apply(cell.stat[levcells, ], 1,
+ function(x) paste(which(x), sep = "", collapse = ":"))
+ inter.nm <- unique(whichbin)
+ #fills <- matrix(0, length(inter.nm), 3)
+ fills <- rep(hsv(1), length(inter.nm))
+ i <- 1
+ for(bn in inter.nm) {
+ who <- as.integer(unlist(strsplit(bn, ":")))
+ fills[i] <- mixcolors2(diff.cols[[1]]$fill[who,],
+ 1/length(who),where = "LUV")
+ i <- i+1
+ }
+ #fills <- LUV(fills)
+ diff.cols[[dl]] <- list(fill = fills,
+ border = gray((i.depth-dl)/i.depth))
+ ##____Full Cell Plotting for Intersecting Cells at Intersection Depth i____
+ i <- 1
+ for(ints in inter.nm) {
+ bin.i <- as.integer(unlist(strsplit(ints, ":"))[1])
+ pcells <-
+ if(eroded[bin.i])
+ bin1 at hbins[[bin.i]]@cell[bin1 at hbins[[bin.i]]@eroded]
+ else bin1 at hbins[[bin.i]]@cell
+ pcells <- which(pcells %in% levcells[whichbin == ints])
+ hexpolygon(x = tmph.xy[[bin.i]]$x[pcells],
+ y = tmph.xy[[bin.i]]$y[pcells], hexC,
+ border = diff.cols[[dl]]$border ,
+ fill = diff.cols[[dl]]$fill[i] )
+ i <- i+1
+ }
+ }
+
+ }
+
+ ##_____________________________Plot Median Cells___________________________
+
+ ## With all these colors floating around I think it would be worth
+ ## porting the 3d hexagon stuff to grid. Then it would be easier
+ ## to distinguish the medians because they would stand out like
+ ## little volcanoes :) NL
+ if(any(eroded)) {
+ hmeds <- matrix(unlist(lapply(bin1 at hbins[eroded],
+ function(x) unlist(getHMedian(x)))),
+ ncol = 2, byrow = TRUE)
+ hexpolygon(x = hmeds[, 1], y = hmeds[, 2], hexC,
+ border = col.control$med.b, fill = col.control$medhex)
+ if(arrows) {
+ for(i in focus) {
+ for(j in focus[focus < i]) {
+ if(abs(hmeds[i, 1] - hmeds[j, 1]) +
+ abs(hmeds[i, 2] - hmeds[j, 2]) > eps)
+ grid.lines(c(hmeds[i, 1],hmeds[j, 1]),
+ c(hmeds[i, 2], hmeds[j, 2]),
+ default.units = "native",
+ arrow=arrow(length=size))
+ #grid.arrows(c(hmeds[i, 1], hmeds[j, 1]),
+ # c(hmeds[i, 2], hmeds[j, 2]),
+ # default.units = "native",
+ # length = size, gp = gpar(lwd = lwd))
+ }
+ }
+ }
+ }
+
+ ##________________Clean Up_______________________________________________
+
+ popViewport()
+ invisible(hvp)
+} ## hdiffplot()
diff --git a/R/hexPlotMA.R b/R/hexPlotMA.R
new file mode 100644
index 0000000..20ed2ba
--- /dev/null
+++ b/R/hexPlotMA.R
@@ -0,0 +1,196 @@
+plotMAhex <- function (MA, array = 1, xlab = "A", ylab = "M",
+ main = colnames(MA)[array],
+ xlim = NULL, ylim = NULL, status = NULL,
+ values, pch, col, cex, nbin=40,
+ zero.weights = FALSE,
+ style = "colorscale", legend = 1.2, lcex = 1,
+ minarea = 0.04, maxarea = 0.8, mincnt = 2,
+ maxcnt = NULL, trans = NULL, inv = NULL,
+ colorcut = NULL,
+ border = NULL, density = NULL, pen = NULL,
+ colramp = function(n){ LinGray(n,beg = 90,end = 15) },
+ newpage = TRUE, type = c("p", "l", "n"),
+ xaxt = c("s", "n"), yaxt = c("s", "n"),
+ verbose = getOption("verbose"))
+{
+ if (!requireNamespace("marray", quietly = TRUE))
+ stop("cannot process objects without package marray")
+ if (!requireNamespace("limma", quietly = TRUE))
+ stop("cannot process objects without package limma")
+ if(is.null(main))main <- ""
+ switch(class(MA),marrayRaw={
+ x <- marray::maA(MA[,array])
+ y <- marray::maM(MA[,array])
+ w <- marray::maW(MA[,array])
+ },RGList = {
+ MA <- limma::MA.RG(MA[, array])
+ array <- 1
+ x <- MA$A
+ y <- MA$M
+ w <- MA$w
+ }, MAList = {
+ x <- as.matrix(MA$A)[, array]
+ y <- as.matrix(MA$M)[, array]
+ if (is.null(MA$weights))
+ w <- NULL
+ else
+ w <- as.matrix(MA$weights)[, array]
+ }, list = {
+ if (is.null(MA$A) || is.null(MA$M))
+ stop("No data to plot")
+ x <- as.matrix(MA$A)[, array]
+ y <- as.matrix(MA$M)[, array]
+ if (is.null(MA$weights))
+ w <- NULL
+ else
+ w <- as.matrix(MA$weights)[, array]
+ }, MArrayLM = {
+ x <- MA$Amean
+ y <- as.matrix(MA$coefficients)[, array]
+ if (is.null(MA$weights))
+ w <- NULL
+ else
+ w <- as.matrix(MA$weights)[, array]
+ }, matrix = {
+ narrays <- ncol(MA)
+ if (narrays < 2)
+ stop("Need at least two arrays")
+ if (narrays > 5)
+ x <- apply(MA, 1, median, na.rm = TRUE)
+ else
+ x <- rowMeans(MA, na.rm = TRUE)
+ y <- MA[, array] - x
+ w <- NULL
+ }, ExpressionSet = {
+ if (!requireNamespace("Biobase", quietly = TRUE))
+ stop("cannot process ExpressionSet objects without package Biobase")
+ narrays <- ncol(Biobase::exprs(MA))
+ if (narrays < 2)
+ stop("Need at least two arrays")
+ if (narrays > 5)
+ x <- apply(Biobase::exprs(MA), 1, median, na.rm = TRUE)
+ else
+ x <- rowMeans(Biobase::exprs(MA), na.rm = TRUE)
+ y <- Biobase::exprs(MA)[, array] - x
+ w <- NULL
+ if (missing(main))
+ main <- colnames(Biobase::exprs(MA))[array]
+ }, AffyBatch = {
+ if (!requireNamespace("Biobase", quietly = TRUE) ||
+ !requireNamespace("affy", quietly = TRUE))
+ stop("cannot process AffyBatch objects without package Biobase and affy")
+ narrays <- ncol(Biobase::exprs(MA))
+ if (narrays < 2)
+ stop("Need at least two arrays")
+ if (narrays > 5)
+ x <- apply(log2(Biobase::exprs(MA)), 1, median, na.rm = TRUE)
+ else
+ x <- rowMeans(log2(Biobase::exprs(MA)), na.rm = TRUE)
+ y <- log2(Biobase::exprs(MA)[, array]) - x
+ w <- NULL
+ if (missing(main))
+ main <- colnames(Biobase::exprs(MA))[array]
+ }, stop("MA is invalid object"))
+ if (!is.null(w) && !zero.weights) {
+ i <- is.na(w) | (w <= 0)
+ y[i] <- NA
+ }
+ if (is.null(xlim))
+ xlim <- range(x, na.rm = TRUE)
+ if (is.null(ylim))
+ ylim <- range(y, na.rm = TRUE)
+
+ hbin <- hexbin(x,y,xbins=nbin,xbnds=xlim,ybnds=ylim, IDs = TRUE)
+ hp <- plot(hbin, legend=legend, xlab = xlab, ylab = ylab, main = main,
+ type='n', newpage=newpage)
+ ## plot the hexagons
+ pushHexport(hp$plot.vp)
+ if(is.null(maxcnt)) maxcnt <- max(hbin at count)
+ if(is.null(colorcut)) colorcut<-seq(0, 1, length = min(17, maxcnt))
+ grid.hexagons(hbin, style=style, minarea = minarea, maxarea = maxarea,
+ mincnt = mincnt, maxcnt= maxcnt, trans = trans,
+ colorcut = colorcut, density = density, border = border,
+ pen = pen, colramp = colramp)
+ if (is.null(status) || all(is.na(status))) {
+ if (missing(pch))
+ pch <- 16
+ if (missing(cex))
+ cex <- 0.3
+ if (missing(col)) {
+ clrs <- colramp(length(colorcut)-1)
+ col <- clrs[1]
+ }
+ pp <- inout.hex(hbin,mincnt)
+ grid.points(x[pp], y[pp], pch = pch[[1]],
+ gp=gpar(cex = cex[1], col=col, fill=col))
+ }
+ else {
+ if (missing(values)) {
+ if (is.null(attr(status, "values")))
+ values <- names(sort(table(status), decreasing = TRUE))
+ else
+ values <- attr(status, "values")
+ }
+ sel <- !(status %in% values)
+ nonhi <- any(sel)
+ if (nonhi) grid.points(x[sel], y[sel], pch = 16, gp=gpar(cex = 0.3))
+ nvalues <- length(values)
+ if (missing(pch)) {
+ if (is.null(attr(status, "pch")))
+ pch <- rep(16, nvalues)
+ else
+ pch <- attr(status, "pch")
+ }
+ if (missing(cex)) {
+ if (is.null(attr(status, "cex"))) {
+ cex <- rep(1, nvalues)
+ if (!nonhi)
+ cex[1] <- 0.3
+ }
+ else
+ cex <- attr(status, "cex")
+ }
+ if (missing(col)) {
+ if (is.null(attr(status, "col"))) {
+ col <- nonhi + 1:nvalues
+ }
+ else
+ col <- attr(status, "col")
+ }
+ pch <- rep(pch, length = nvalues)
+ col <- rep(col, length = nvalues)
+ cex <- rep(cex, length = nvalues)
+ for (i in 1:nvalues) {
+ sel <- status == values[i]
+ grid.points(x[sel], y[sel], pch = pch[[i]], gp=gpar(cex = cex[i], col = col[i]))
+ }
+ }
+ popViewport()
+ if (legend > 0) {
+ inner <- getPlt(hp$plot.vp, ret.unit="inches", numeric=TRUE)[1]
+ inner <- inner/hbin at xbins
+ ysize <- getPlt(hp$plot.vp, ret.unit="inches", numeric=TRUE)[2]
+ pushViewport(hp$legend.vp)
+ grid.hexlegend(legend, ysize=ysize, lcex = lcex, inner = inner,
+ style= style, minarea= minarea, maxarea= maxarea,
+ mincnt= mincnt, maxcnt= maxcnt,
+ trans=trans, inv=inv,
+ colorcut = colorcut,
+ density = density, border = border, pen = pen,
+ colramp = colramp)
+
+ #if (is.list(pch))
+ # legend(x = xlim[1], y = ylim[2], legend = values,
+ # fill = col, col = col, cex = 0.9)
+ #else legend(x = xlim[1], y = ylim[2], legend = values,
+ # pch = pch, , col = col, cex = 0.9)
+ popViewport()
+ }
+ invisible(list(hbin = hbin, plot.vp = hp$plot.vp, legend.vp = hp$legend.vp))
+}
+
+hexMA.loess <- function(pMA, span = .4, col = 'red', n = 200)
+{
+ fit <- hexVP.loess(pMA$hbin, pMA$plot.vp, span = span, col = col, n = n)
+ invisible(fit)
+}
diff --git a/R/hexViewport.R b/R/hexViewport.R
new file mode 100644
index 0000000..2adb1b4
--- /dev/null
+++ b/R/hexViewport.R
@@ -0,0 +1,253 @@
+setOldClass("unit")
+setOldClass("viewport")
+
+smartBnds <- function(hbin, eps=.05)
+{
+ hxy <- hcell2xy(hbin)
+ xr <- range(hxy$x)
+ yr <- range(hxy$y)
+ dx <- diff(xr)
+ dy <- diff(yr)
+ lambda <- function(a) pmax(log(a), 1)
+ epsx <- c(-1,1)*(dx*eps/lambda(dx))
+ epsy <- c(-1,1)*(dy*eps/lambda(dy))
+ sx <- hbin at xbins/diff(hbin at xbnds)
+ sy <- (hbin at xbins * hbin at shape)/diff(hbin at ybnds)
+ inner <- 0.5
+ outer <- 1/sqrt(3)
+ dx <- inner/sx
+ dy <- outer/sy
+ #xb <- dx/(hbin at xbins+1)
+ #yb <- dy/((1/sqrt(3))*(hbin at xbins+1)*hbin at shape)
+ list(xr = xr+ c(-dx,dx)+ epsx,
+ yr = yr+ c(-dy,dy)+ epsy)
+}
+
+rname <- function(n, chars = letters)
+{
+ ## random name with n characters
+ paste(sample(chars, size = n, replace = TRUE), collapse="")
+}
+
+setClass("hexVP",
+ representation(hexVp.on = "viewport", hexVp.off = "viewport",
+ mar = "unit", fig = "unit", plt = "unit",
+ xscale = "numeric", yscale = "numeric",shape="numeric",
+ hp.name="character")
+ )
+
+hexViewport <-
+function(x, offset = unit(0,"inches"), mar = NULL,
+ xbnds = NULL, ybnds = NULL, newpage = FALSE,
+ clip ="off", vp.name=NULL)
+{
+ if(!is(x,"hexbin"))
+ stop("first argument must be a hexbin object.")
+ stopifnot(is.unit(offset))
+
+ hvp <- new("hexVP")
+ if (newpage)
+ grid.newpage()
+
+ if(is.null(mar)) {
+ mar <- unit(0.1 + c(5,4,4,2),"lines")
+ }
+ else {
+ if(!is.unit(mar)) stop("'mar' must be specified in unit()s")
+ if(length(mar) == 1)
+ mar <- rep(mar, 4)
+ else if(length(mar) != 4)
+ stop("'mar' must have length 1 or 4")
+ }
+ ## in both cases
+ mai <- as.numeric(convertUnit(mar, "inches"))
+ vpin <- c(convertWidth (unit(1,"npc"),"inches"), convertHeight(unit(1,"npc"),"inches"))
+ fig <- c(as.numeric(convertUnit(unit(vpin[1],"inches") - offset,"inches")), as.numeric(vpin[2]))
+ pin <- c(fig[1]-mai[2]-mai[4], fig[2]-mai[1]-mai[3])
+ xsize <- pin[1]
+ ysize <- pin[2]
+
+ ## The point is to optimize the placement
+ ## and plotting area of the plotting window with
+ ## the constraint that the margins are preserved
+ ## to within some epsilon. This is going to get even
+ ## harder for cases where the complex layouts are
+ ## being constructed. NL -- I think it is fixed now (NL --3/22/2005)
+
+ ## Now find the maximum rectangle in fig that
+ ## has the correct aspect ratio and does not spill over epsilon into
+ ## the margins, i.e. ysize/xsize - aspect.ratio < eps and
+ ## xsize < fig[1], ysize < fig[2]
+
+ if(x at shape * xsize <= ysize) {
+ ##center <- (ysize - x at shape * xsize)/2
+ center <- (ysize - x at shape * xsize)/2
+ mai[1] <- mai[1] + center
+ mai[3] <- mai[3] + center
+ ysize <- x at shape * xsize
+ } else {
+ center <- (xsize - ysize/x at shape)/2
+ mai[2] <- mai[2] + center
+ mai[4] <- mai[4] + center
+ xsize <- ysize/x at shape
+ }
+ ##fig <- c(pin[1]+mai[2]+ mai[4],fig[2])
+ pin <- c(xsize,ysize)
+ mar <- c(convertUnit(unit(mai[1],"inches"),"lines"),
+ convertUnit(unit(mai[2],"inches"),"lines"),
+ convertUnit(unit(mai[3],"inches"),"lines"),
+ convertUnit(unit(mai[4],"inches"),"lines"))
+ ##pin <- c(fig[1]-(mai[2] + mai[4]),
+ ## fig[2]-(mai[1] + mai[3]))
+ margins <- rep(as.numeric(mar), length.out = 4)
+ wd <- convertUnit(unit(pin[1],"inches"),"npc")
+ ## (unit(sum(margins[c(2, 4)]), "lines") +
+ ## convertUnit(unit(legend,"inches"),"lines"))
+ ## Oy, mi stupido! This is the problem, need to get the bounds right
+ ## here. Fixed, do we need to guard against others stupidity and put some
+ ## checks on xbnds and ybnds? (NL,4/1/2005)
+ if(is.null(vp.name))
+ vp.name <- rname(5)
+ xyb <- smartBnds(x)
+ hvp at xscale <- xs <- if(is.null(xbnds)) xyb$xr else xbnds
+ hvp at yscale <- ys <- if(is.null(ybnds)) xyb$yr else ybnds
+ ht <- unit(1, "npc") - unit(sum(margins[c(1,3)]), "lines")
+ hvp at hexVp.off <-
+ viewport(x = unit(margins[2], "lines"),
+ y = unit(margins[1], "lines"),
+ width = wd, height = ht, xscale = xs, yscale = ys,
+ just = c("left", "bottom"), default.units = "native",
+ clip = "off", name = paste(vp.name,".off",sep=""))
+ hvp at hexVp.on <-
+ viewport(x = unit(margins[2], "lines"),
+ y = unit(margins[1], "lines"),
+ width = wd, height = ht, xscale = xs, yscale = ys,
+ just = c("left", "bottom"), default.units = "native",
+ clip = "on", name = paste(vp.name,".on",sep=""))
+ hvp at mar <- unit(mar,"lines")
+ hvp at fig <- convertUnit(unit(fig,"inches"),"npc")
+ hvp at plt <- convertUnit(unit(pin,"inches"),"npc")
+ hvp at shape <- x at shape
+ ##hvp at leg <-convertUnit(offset,"npc")
+ hvp
+}
+
+## Potentially:
+## setGeneric("grid:::pushViewport")
+## setMethod("pushViewport", signature(x="hexVP"),
+## function(hvp) { pushViewport(hvp at hexVp) })
+
+pushHexport <- function(hvp, clip="off")
+{
+ if(!is(hvp, "hexVP"))
+ stop("1st argument must be 'hexVP' object")
+ pushViewport(if(clip=="on") hvp at hexVp.on else hvp at hexVp.off)
+}
+
+## maybe in the future
+## setMethod("push",signature("hexVP"), pushHexport)
+
+setGeneric("getMargins", function(x, ret.unit = "npc", numeric = FALSE)
+ standardGeneric("getMargins"))
+setMethod("getMargins", "hexVP",
+ function(x, ret.unit = "npc", numeric = FALSE){
+ mar <- convertUnit(x at mar,ret.unit)
+ if(numeric) as.numeric(mar) else mar
+ })
+
+setGeneric("getPlt", function(x, ret.unit = "npc", numeric = FALSE)
+ standardGeneric("getPlt"))
+setMethod("getPlt", "hexVP",
+ function(x, ret.unit = "npc", numeric = FALSE){
+ plt <- convertUnit(x at plt,ret.unit)
+ if(numeric) as.numeric(plt) else plt
+ })
+
+setGeneric("getFig", function(x, ret.unit = "npc", numeric = FALSE)
+ standardGeneric("getFig"))
+setMethod("getFig", "hexVP",
+ function(x, ret.unit = "npc", numeric = FALSE){
+ fig <- convertUnit(x at fig,ret.unit)
+ if(numeric) as.numeric(fig) else fig
+ })
+
+## MM doesn't think it's ok to "pollute" the generic-space
+## just for basic slot accessors :
+
+## setGeneric("getXscale", function(x)standardGeneric("getXscale"))
+## setMethod("getXscale", "hexVP", function(x){ x at xscale })
+
+## setGeneric("getYscale", function(x)standardGeneric("getYscale"))
+## setMethod("getYscale", "hexVP", function(x){ x at yscale })
+
+hexVP.abline <- function(hvp, a = NULL, b = NULL, h = numeric(0),
+ v = numeric(0), col = 'black',
+ lty = 1, lwd = 2, ...)
+{
+ pushHexport(hvp, clip = 'on')
+ col.line <- col
+ if (!is.null(a)) {
+ if (inherits(a, "lm")) {
+ coeff <- coef(a)
+ }
+ else if (!is.null(tryCatch(coef(a), error = function(e) NULL)))
+ coeff <- coef(a)
+ else coeff <- c(a, b)
+ if (length(coeff) == 1)
+ coeff <- c(0, coeff)
+ if (coeff[2] == 0)
+ h <- c(h, coeff[1])
+ else if (!any(is.null(coeff))) {
+ xx <- current.viewport()$xscale
+ yy <- current.viewport()$yscale
+ x <- numeric(0)
+ y <- numeric(0)
+ ll <- function(i, j, k, l)
+ (yy[j] - coeff[1] - coeff[2] * xx[i]) * (yy[l] - coeff[1] - coeff[2] * xx[k])
+ if (ll(1, 1, 2, 1) <= 0) {
+ y <- c(y, yy[1])
+ x <- c(x, (yy[1] - coeff[1])/coeff[2])
+ }
+ if (ll(2, 1, 2, 2) <= 0) {
+ x <- c(x, xx[2])
+ y <- c(y, coeff[1] + coeff[2] * xx[2])
+ }
+ if (ll(2, 2, 1, 2) <= 0) {
+ y <- c(y, yy[2])
+ x <- c(x, (yy[2] - coeff[1])/coeff[2])
+ }
+ if (ll(1, 2, 1, 1) <= 0) {
+ x <- c(x, xx[1])
+ y <- c(y, coeff[1] + coeff[2] * xx[1])
+ }
+ if (length(x) > 0)
+ grid.lines(x = x, y = y, default.units = "native",
+ gp = gpar(col = col.line, lty = lty, lwd = lwd))
+ }
+ }
+ h <- as.numeric(h)
+ v <- as.numeric(v)
+ for (i in seq(along = h))
+ grid.lines(y = rep(h[i], 2), default.units = "native",
+ gp = gpar(col = col.line, lty = lty, lwd = lwd))
+ for (i in seq(along = v))
+ grid.lines(x = rep(v[i], 2), default.units = "native",
+ gp = gpar(col = col.line, lty = lty, lwd = lwd))
+ popViewport()
+}
+
+hexVP.loess <- function(hbin, hvp = NULL, span = 0.4, col = 'red', n = 200)
+{
+ fit <- loess(hbin at ycm ~ hbin at xcm, weights = hbin at count, span = span)
+ if(!is.null(hvp)) {
+ pushHexport(hvp, clip = 'on')
+# grid.lines(seq(0,16, length = n),
+# predict(fit,seq(0,16, length = n)),
+# gp = gpar(col = col), default.units = 'native')
+ grid.lines(seq(hbin at xbnds[1], hbin at xbnds[2], length = n),
+ predict(fit,seq(hbin at xbnds[1], hbin at xbnds[2], length = n)),
+ gp = gpar(col = col), default.units = 'native')
+ popViewport()
+ }
+ invisible(fit)
+}
diff --git a/R/hexbin.s4.R b/R/hexbin.s4.R
new file mode 100644
index 0000000..634a442
--- /dev/null
+++ b/R/hexbin.s4.R
@@ -0,0 +1,355 @@
+## namespace *internal* function:
+addBit <- function(bnds, f = 0.05) bnds + c(-f, f) * diff(bnds)
+hexbin <-
+ function(x, y = NULL, xbins = 30, shape = 1,
+ xbnds = range(x), ybnds = range(y),
+ xlab = NULL, ylab = NULL, IDs = FALSE)
+{
+ call <- match.call()
+ ## (x,y, xlab, ylab) dealing
+ xl <- if (!missing(x)) deparse(substitute(x))
+ yl <- if (!missing(y)) deparse(substitute(y))
+ xy <- xy.coords(x, y, xl, yl)
+ ch0 <- function(u) if(is.null(u)) "" else u
+ xlab <- if (is.null(xlab)) ch0(xy$xlab) else xlab
+ ylab <- if (is.null(ylab)) ch0(xy$ylab) else ylab
+ if(! (is.character(xlab) || is.expression(xlab)))
+ stop("xlab must be a character or expression")
+ if(! (is.character(ylab) || is.expression(ylab)))
+ stop("ylab must be a character or expression")
+
+ x <- xy$x
+ y <- xy$y
+ n <- length(x)
+ na <- is.na(x) | is.na(y)
+ has.na <- any(na)
+ if (has.na) {
+ ok <- !na
+ x <- x[ok]
+ y <- y[ok]
+ n0 <- n
+ na.pos <- which(na)
+ n <- length(x)
+ }
+ if(diff(xbnds) <= 0)
+ stop("xbnds[1] < xbnds[2] is not fulfilled")
+ if(!missing(xbnds) && any(sign(xbnds - range(x)) == c(1,-1)))
+ stop("'xbnds' must encompass range(x)")
+ if(diff(ybnds) <= 0)
+ stop("ybnds[1] < ybnds[2] is not fulfilled")
+ if(!missing(ybnds) && any(sign(ybnds - range(y)) == c(1,-1)))
+ stop("'ybnds' must encompass range(y)")
+ jmax <- floor(xbins + 1.5001)
+ #imax <- 2 * floor((xbins * shape)/sqrt(3) + 1.5001)
+ c1 <- 2 * floor((xbins *shape)/sqrt(3) + 1.5001)
+ imax <- trunc((jmax*c1 -1)/jmax + 1)
+ lmax <- jmax * imax
+ ans <- .Fortran("hbin",
+ x = as.double(x),
+ y = as.double(y),
+ cell = integer(lmax),
+ cnt = integer(lmax),
+ xcm = double(lmax),
+ ycm = double(lmax),
+ xbins = as.double(xbins),
+ shape = as.double(shape),
+ xbnds = as.double(xbnds),
+ ybnds = as.double(ybnds),
+ dim = as.integer(c(imax, jmax)),
+ n = as.integer(n),
+ cID = if(IDs) integer(n) else as.integer(-1),
+ PACKAGE = "hexbin")[-(1:2)]
+
+ ## cut off extraneous stuff
+ if(!IDs) ans$cID <- NULL
+ if(IDs && has.na) {
+ ok <- as.integer(ok)
+ ok[!na] <- ans$cID
+ ok[na] <- NA
+ ans$cID <- ok
+ }
+ nc <- ans$n
+ length(ans$cell) <- nc
+ length(ans$cnt) <- nc
+ length(ans$xcm) <- nc
+ length(ans$ycm) <- nc
+ if(sum(ans$cnt) != n) warning("Lost counts in binning")
+ new("hexbin",
+ cell = ans$cell, count = ans$cnt,
+ xcm = ans$xcm, ycm = ans$ycm, xbins = ans$xbins,
+ shape = ans$shape, xbnds = ans$xbnds , ybnds = ans$ybnds,
+ dimen = c(imax, jmax), n = n, ncells = ans$n,
+ call = call, xlab = xlab, ylab = ylab, cID = ans$cID, cAtt = integer(0))
+ #dimen = ans$dim
+}## hexbin
+
+setClassUnion("integer or NULL",# < virtual class, used in 'cID' slot
+ members = c("integer","NULL"))
+## MM: I've learned that we should think twice before defining such
+## "or NULL" classes:
+## setClassUnion("vector or NULL",# < virtual class, used in 'cAtt' slot
+## members = c("vector","NULL"))
+
+setClass("hexbin",
+ representation(cell = "integer", count = "numeric",##count = "integer",
+ xcm = "numeric", ycm = "numeric", xbins = "numeric",
+ shape = "numeric", xbnds = "numeric",
+ ybnds = "numeric", dimen = "numeric",
+ n = "integer", ncells = "integer", call = "call",
+ xlab = "vector", ylab = "vector",
+ #xlab = "character", ylab = "character",
+ cID = "integer or NULL", cAtt = "vector")## "or NULL"
+ )
+
+
+#setIs("hexbin", function(hbin) class(hbin)=="hexbin")
+
+## FIXME: add 'validity checking method!
+
+setGeneric("hcell2xy", function(hbin, check.erosion = TRUE)
+ standardGeneric("hcell2xy"))
+setMethod("hcell2xy", "hexbin", function(hbin, check.erosion = TRUE)
+{
+ xbins <- hbin at xbins
+ xbnds <- hbin at xbnds
+ c3 <- diff(xbnds)/xbins
+ ybnds <- hbin at ybnds
+ c4 <- (diff(ybnds) * sqrt(3))/(2 * hbin at shape * xbins)
+ jmax <- hbin at dimen[2]
+ cell <- hbin at cell - 1
+ i <- cell %/% jmax
+ j <- cell %% jmax
+ y <- c4 * i + ybnds[1]
+ x <- c3 * ifelse(i %% 2 == 0, j, j + 0.5) + xbnds[1]
+ if(check.erosion && inherits(hbin,"erodebin"))
+ list(x = x[hbin at eroded], y = y[hbin at eroded])
+ else
+ list(x = x, y = y)
+})
+
+setGeneric("getHexDxy", function(hbin) standardGeneric("getHexDxy"))
+setMethod("getHexDxy", "hexbin", function(hbin){
+ sx <- hbin at xbins/diff(hbin at xbnds)
+ sy <- (hbin at xbins * hbin at shape)/diff(hbin at ybnds)
+ list(dx=.5/sx, dy=(1/sqrt(3))/(2*sy))
+})
+
+
+setClass("erodebin", representation("hexbin",
+ eroded = "logical",
+ cdfcut = "numeric",
+ erode = "integer"))
+
+setGeneric("erode", function(hbin, cdfcut = 0.5) standardGeneric("erode"))
+
+## currently define the 'hexbin' method (also) as standalone function:
+erode.hexbin <- function(hbin, cdfcut = 0.5)
+{
+ if(!is(hbin,"hexbin")) stop("first argument must be a hexbin object")
+ #bin.att <- attributes(hbin)
+ cell <- hbin at cell
+ cnt <- hbin at count
+ tmp <- sort(cnt)
+ cdf <- cumsum(tmp)/sum(cnt)
+ good <- cdfcut <= cdf
+ if(!any(good))
+ return("no cells selected")
+ crit <- min(tmp[good])
+ good <- crit <= cnt
+ cell <- cell[good]
+ cnt <- cnt[good]
+ #hbin at cell <- cell
+ #hbin at count <- cnt
+ n <- length(cell)
+ bdim <- hbin at dimen
+ L <- bdim[1] * bdim[2]
+ ans <- .Fortran("herode",
+ cell = as.integer(cell),
+ cnt = as.integer(cnt),
+ n = n,
+ bdim = as.integer(bdim),
+ erode = integer(L),
+ ncnt = integer(L),
+ ncell = integer(L),
+ sides = integer(L),
+ neib = integer(6 * L),
+ exist = logical(L + 1),
+ PACKAGE = "hexbin") $ erode
+ length(ans) <- n
+ ehbin <- new("erodebin", hbin, cdfcut = cdfcut, eroded = good, erode = ans)
+ #hbin at erode <- ans
+ #class(hbin) <- c(class(hbin),"erodebin")
+ ehbin
+}
+setMethod("erode", "hexbin", erode.hexbin)
+
+setGeneric("getHMedian", function(ebin) standardGeneric("getHMedian"))
+setMethod("getHMedian", "erodebin", function(ebin)
+ {
+ xy <- hcell2xy(ebin)
+ stopifnot(1 == length(med <- which.max(ebin at erode)))
+ med.x <- xy$x[med]
+ med.y <- xy$y[med]
+
+ list(x = med.x, y = med.y)
+ })
+
+## Still define the 'hexbin' plot method (also) as standalone function:
+## This is deprecated!
+gplot.hexbin <-
+ function(x, style = "colorscale",
+ legend = 1.2, lcex = 1,
+ minarea = 0.04, maxarea = 0.8, mincnt = 1, maxcnt = max(x at count),
+ trans = NULL, inv = NULL,
+ colorcut = seq(0, 1, length = min(17, maxcnt)),
+ border = NULL, density = NULL, pen = NULL,
+ colramp = function(n) LinGray(n, beg = 90, end = 15),
+ xlab = NULL, ylab = NULL, main = "", newpage = TRUE,
+ type = c("p", "l", "n"), xaxt = c("s", "n"), yaxt = c("s", "n"),
+ clip="on", verbose = getOption("verbose"))
+{
+ if(!is(x,"hexbin"))
+ stop("first argument must be a hexbin object")
+ if(minarea < 0)
+ stop("Minimum area must be non-negative")
+ if(maxarea > 1)
+ warning("Maximum area should be <= 1 this leads to overlapping hexagons")
+ if(minarea > maxarea)
+ stop("Minarea must be <= maxarea")
+ if (length(colorcut) > 1) { # a sequence 0,...,1
+ if(colorcut[1] != 0)
+ stop("Colorcut lower boundary must be 0")
+ if(colorcut[length(colorcut)] != 1)
+ stop("Colorcut upper boundary must be 1")
+ }
+ else {
+ colorcut <-
+ if(colorcut > 1) seq(0, 1, length = min(c(17, colorcut, maxcnt)))
+ else 1
+ }
+
+ if(is.logical(legend)) {
+ if(legend)
+ stop("Give the legend width")
+ else legend <- 0
+ } else stopifnot(is.numeric(legend) && length(legend) == 1)
+
+ type <- match.arg(type)
+ xaxt <- match.arg(xaxt)
+ yaxt <- match.arg(yaxt)
+
+ ## ----- plotting starts ------------------------
+ if (newpage) grid.newpage()
+ hv.ob <- hexViewport(x, offset = unit(legend,"inches"))
+ pushViewport(hv.ob at hexVp.off)
+ grid.rect()
+ if(xaxt != "n") grid.xaxis()
+ if(yaxt != "n") grid.yaxis()
+ ## xlab, ylab, main :
+ if(is.null(xlab)) xlab <- x at xlab
+ if(is.null(ylab)) ylab <- x at ylab
+ if(nchar(xlab) > 0)
+ grid.text(xlab, y = unit(-2, "lines"), gp = gpar(fontsize = 16))
+ if(nchar(ylab) > 0)
+ grid.text(ylab, x = unit(-2, "lines"), gp = gpar(fontsize = 16), rot = 90)
+ if(nchar(main) > 0)
+ grid.text(main, y = unit(1, "npc") + unit(1.5, "lines"),
+ gp = gpar(fontsize = 18))
+ if(type != "n") {
+ if(clip == "on") {
+ popViewport()
+ pushViewport(hv.ob at hexVp.on)
+ }
+ grid.hexagons(x, style = style, minarea = minarea, maxarea = maxarea,
+ mincnt = mincnt, maxcnt = maxcnt, check.erosion = FALSE,
+ trans = trans, colorcut = colorcut, density = density,
+ border = border, pen = pen,
+ colramp = colramp, verbose = verbose)
+ }
+
+ popViewport()# plot
+ #popViewport()# fig
+ ## ----- Legend ------------------------
+ if(legend > 0) {
+ if(!is.null(trans) && is.null(inv))
+ stop("Must supply the inverse transformation")
+ if(verbose)
+ cat("plot.hexbin( legend > 0): ... hex.legend()\n")
+ inner <- getPlt(hv.ob, ret.unit = "inches", numeric = TRUE)[1]/x at xbins
+ ##inner <- as.numeric(convertUnit(hv.ob at plt[1],"inches"))/x at xbins
+ ##outer <- (inner * sqrt(3))/2
+ ##switch(style,
+ ## lattice = ,
+ ## centroids = {
+ ## if(length(colorcut) * outer > ysize - 1) {
+ ## warning("Colorcut is being shortened")
+ ## colorcut <- seq(0, 1,
+ ## max(1, floor((ysize - 1)/outer)))
+ ## }
+ ## }
+ ## )
+ ysize <- getPlt(hv.ob, ret.unit = "inches", numeric = TRUE)[2]
+ #as.numeric(convertUnit(hv.ob at plt[2],"inches"))
+ legVp <- viewport(x = unit(1,"npc") -
+ convertX(unit(legend,"inches"), "npc"),
+ #y = convertY(unit(mai[1],"inches"),"npc"),
+ y = hv.ob at mar[1],
+ #height = unit(1,"npc") -
+ #convertY(unit(mai[3]+mai[1],"inches"),"npc"),
+ height = unit(1,"npc")-(hv.ob at mar[1]+ hv.ob at mar[3]),
+ width = convertUnit(unit(legend,"inches"),"npc"),
+ default.units = "native",
+ just = c("left","bottom"),
+ xscale = c(0, legend),
+ yscale = c(0, ysize))
+ if(type != "n") {
+ pushViewport(legVp)
+ grid.hexlegend(legend, ysize = ysize, lcex = lcex, inner = inner,
+ style = style, minarea = minarea, maxarea = maxarea,
+ mincnt = mincnt, maxcnt = maxcnt,
+ trans = trans, inv = inv, colorcut = colorcut,
+ density = density, border = border, pen = pen,
+ colramp = colramp)
+ popViewport()
+ }
+ }
+
+ invisible(list(plot.vp = hv.ob, legend.vp = if(legend) legVp))
+} ## gplot.hexbin()
+
+setMethod("plot", signature(x = "hexbin", y = "missing"), gplot.hexbin)
+
+setMethod("show", "hexbin",
+ function(object) {
+ cat("'hexbin' object from call:", deparse(object at call), "\n")
+ dm <- object at dimen
+ cat("n =", object at n, " points in nc =", object at ncells,
+ " hexagon cells in grid dimensions ", dm[1], "by", dm[2],"\n")
+ invisible(object)
+ })
+
+setMethod("summary", "hexbin",
+ function(object, ...) {
+ show(object, ...)
+ print(summary(data.frame(cell = object at cell, count = object at count,
+ xcm = object at xcm, ycm = object at ycm),
+ ...))
+ if(!is.null(object at cID)) {
+ cat("IDs: "); str(object at cID)
+ }
+ })
+
+
+
+if(FALSE) { ##-- todo --
+#setMethod("identify"
+identify.hexbin <- function(x, labels = x$cnt, offset = 0, ...)
+{
+ if(length(labels) != x$n)
+ stop("labels not the same length as number of cells")
+ ##NL: Should this be a warning?
+
+ ## -> typically default method:
+ identify(hcell2xy(x), labels = labels, offset = offset, ...)
+}
+}#not yet
diff --git a/R/hexbinList.R b/R/hexbinList.R
new file mode 100644
index 0000000..7938ab6
--- /dev/null
+++ b/R/hexbinList.R
@@ -0,0 +1,106 @@
+hexList <- function(x,y=NULL,given=NULL,xbins=30,shape=1,
+ xbnds = NULL, ybnds = NULL,
+ xlab = NULL, ylab = NULL)
+{
+ xl <- if (!missing(x)) deparse(substitute(x))
+ yl <- if (!missing(y)) deparse(substitute(y))
+ xy <- xy.coords(x, y, xl, yl)
+ if(length(given)!=length(xy$x) | is.null(given))
+ stop("Given is is different length from x and y")
+ if(is.factor(given))
+ given <- as.character(given)
+ clss <- unique(given)
+ if(is.null(xbnds))
+ xbnds <- range(xy$x)
+ if(is.null(ybnds))
+ ybnds <- range(xy$y)
+ hbins <- vector(mode = "list",length=length(clss))
+ i <- 1
+ for(g in clss){
+ hbins[[i]] <- hexbin(xy$x[given==g],xy$y[given==g],
+ xbins=xbins,shape=shape,xbnds=xbnds,ybnds=ybnds)
+ i <- i+1
+ }
+ mx <- max(unlist(lapply(hbins,function(h)max(h at count))))
+ mn <- min(unlist(lapply(hbins,function(h)min(h at count))))
+ hl <- new("hexbinList",n=length(hbins),hbins=hbins, Xbnds=xbnds,
+ Ybnds=ybnds, Xbins=integer(xbins), Shape=shape, Bnames=clss,
+ CntBnds=c(mn,mx))
+ hl
+}
+
+
+setClass("hexbinList",
+ representation(n="integer", hbins="vector",
+ Xbnds="numeric", Ybnds="numeric",
+ Xbins="numeric", Shape="numeric",
+ Bnames="character", CntBnds="numeric")
+
+ )
+
+
+bnds.check <- function(binlst, xb = TRUE, yb = TRUE)
+{
+ xb <-
+ if(xb) {
+ b <- binlst[[1]]@xbnds
+ all(unlist(lapply(binlst, function(x, bnd) all(x at xbnds == bnd), b)))
+ } else TRUE
+ yb <-
+ if(yb) {
+ b <- binlst[[1]]@ybnds
+ all(unlist(lapply(binlst, function(y, bnd) all(y at ybnds == bnd), b)))
+ } else TRUE
+ xb & yb
+}
+
+xbins.check <- function(binlst)
+{
+ xb <- binlst[[1]]@xbins
+ all(unlist(lapply(binlst, function(y, xbin)all(y at xbins == xbin), xb)))
+}
+
+shape.check <- function(binlst)
+{
+ xs <- binlst[[1]]@shape
+ all(unlist(lapply(binlst, function(y, xsh)all(y at shape == xsh), xs)))
+}
+
+list2hexList <- function(binlst)
+{
+ if(length(binlst) < 2)
+ stop(" need at least 2 hex bin objects")
+ if(!all(unlist(lapply(binlst, is, "hexbin"))))
+ stop("All Elements of list must be hexbin objects")
+ if(!bnds.check(binlst))
+ stop("All bin objects in list need the same xbnds and ybnds")
+ if(!xbins.check(binlst))
+ stop("All bin objects in list need the same number of bins")
+ if(!shape.check(binlst))
+ stop("All bin objects in list need the same shape parameter")
+ mx <- max(unlist(lapply(binlst,function(h)max(h at count))))
+ mn <- min(unlist(lapply(binlst,function(h)min(h at count))))
+ xbins <- binlst[[1]]@xbins
+ xbnds <- binlst[[1]]@xbnds
+ ybnds <- binlst[[1]]@ybnds
+ shape <- binlst[[1]]@shape
+ hl <- new("hexbinList",n=length(binlst),hbins=binlst, Xbnds=xbnds,
+ Ybnds=ybnds, Xbins=xbins, Shape=shape,
+ Bnames=names(binlst), CntBnds=c(mn,mx))
+ hl
+}
+
+setAs("list","hexbinList",function(from)list2hexList(from))
+
+#setMethod("[", "hexbinList", function(hbl,i,...)
+#{
+# if( length(list(...)) > 0 )
+# stop("extra subscripts cannot be handled")
+# if(missing(i)) hbl
+# hbl at hbins[i]
+#})
+
+##setMethod("[[", "hexbinList", function(hbl)
+##{
+
+##})
diff --git a/R/hexbinplot.R b/R/hexbinplot.R
new file mode 100644
index 0000000..e8ede8c
--- /dev/null
+++ b/R/hexbinplot.R
@@ -0,0 +1,777 @@
+## lattice version of gplot.hexbin
+
+## There are two major problems. (1) For comparability across panels,
+## we want the same mincnt and maxcnt in all panels. However, a
+## suitable default can really only be determined at printing time,
+## since it would depend on the physical dimensions of the panel. (2)
+## there is no proper way to communicate the mincnt and maxcnt to the
+## legend.
+
+## Tentative solution: the counts can be calculated once enough things
+## are known, namely the aspect ratio, xbins and [xy]bnds. An
+## important question then is whether [xy]bnds should be [xy]lim or
+## range([xy]). Both should be allowed, since [xy]lim makes them
+## comparable, range([xy]) potentially shows more detail. For
+## relation != "same", both are more or less similar. An important
+## observation is that with range([xy]), 'shape = aspect ratio of
+## panel' does not guarantee symmetric hexagons, so shape has to be
+## different for each panel.
+
+## Only feasible approach I can think of is to produce the trellis
+## object first (with known aspect, so aspect="fill" is absolutely
+## no-no), then analyze the limits and relevant panel arguments to get
+## 'maxcnt' (essentially doing a dry run of the panel calculations).
+## This needs undocumented knowledge of the trellis object, which is
+## kinda not good, but at least it gets the job done. Once we know
+## maxcnt, we can also set up a suitable legend function.
+
+## Unfortunately, this has the potential to screw up update calls that
+## modify certain things. Is there any way to capture those? Maybe
+## make a new class that inherits from "trellis". For now, we'll
+## pretend that the problem doesn't exist.
+
+
+## tool borrowed from lattice
+updateList <- function (x, val)
+{
+ if (is.null(x)) x <- list()
+ modifyList(x, val)
+}
+
+
+prepanel.hexbinplot <-
+ function(x, y, type = character(0),...)
+{
+ if('tmd'%in%type){
+ tmp <- x
+ x <- (y + x)/sqrt(2)
+ y <- (y - tmp)/sqrt(2)
+ }
+ ans <-
+ list(xlim = range(x, finite = TRUE),
+ ylim = range(y, finite = TRUE),
+ dx = IQR(x,na.rm=TRUE),
+ dy = IQR(y,na.rm=TRUE))
+}
+
+
+panel.hexbinplot <-
+ function(x, y, ..., groups = NULL)
+{
+ if (is.null(groups)) panel.hexbin(x, y, ...)
+ else panel.hexpose(x, y, ..., groups = groups)
+}
+
+
+panel.hexbin <-
+ function(x, y,
+ xbins = 30,
+ xbnds = c("data", "panel"), # was: xbnds = c("panel", "data"),
+ ybnds = c("data", "panel"), # was: ybnds = c("panel", "data"),
+
+ ## special args
+ .prelim = FALSE,
+ .cpl = current.panel.limits(),
+ .xlim = .cpl$xlim,
+ .ylim = .cpl$ylim,
+ .aspect.ratio = 1, # default useful with splom(, panel = panel.hexbin)
+
+ type = character(0),
+ ...,
+ check.erosion = FALSE)
+{
+ if ("tmd" %in% type) {
+ tmp <- x
+ x <- (y + x)/sqrt(2)
+ y <- (y - tmp)/sqrt(2)
+ }
+ if (is.character(xbnds))
+ xbnds <-
+ switch(match.arg(xbnds),
+ panel = .xlim,
+ data = range(x, finite = TRUE))
+ if (is.character(ybnds))
+ ybnds <-
+ switch(match.arg(ybnds),
+ panel = .ylim,
+ data = range(y, finite = TRUE))
+ shape <-
+ .aspect.ratio * (diff(ybnds) / diff(.ylim)) /
+ (diff(xbnds) / diff(.xlim))
+ if (!missing(check.erosion))
+ warning("explicit 'check.erosion' specification ignored")
+ h <- hexbin(x = x, y = y,
+ xbins = xbins, shape = shape,
+ xbnds = xbnds, ybnds = ybnds)
+ if (.prelim)
+ return(max(h at count))
+
+ ## have to do this because grid.hexagons croaks with unrecognized
+ ## arguments:
+ args <- list(dat = h, check.erosion = FALSE, ...)
+ keep <- names(args) %in% names(formals(grid.hexagons))
+
+ if ('g' %in% type) panel.grid(h = -1, v = -1)
+ if ('hg' %in% type) panel.hexgrid(h)
+
+ do.call("grid.hexagons", args[keep])
+
+ if ("r" %in% type) panel.lmline(x, y, ...)
+ if ("smooth" %in% type) panel.hexloess(h,...)
+ invisible()
+}
+
+panel.hexboxplot <-
+ function(x, y,
+ xbins = 30,
+ xbnds = c("data", "panel"), # was: xbnds = c("panel", "data"),
+ ybnds = c("data", "panel"), # was: ybnds = c("panel", "data"),
+
+ ## special args
+ .prelim = FALSE,
+ .cpl = current.panel.limits(),
+ .xlim = .cpl$xlim,
+ .ylim = .cpl$ylim,
+ .aspect.ratio = 1,
+
+ type = character(0),
+ cdfcut=.25,
+ shadow=.05,
+ ...,
+ check.erosion = TRUE)
+{
+ if (is.character(xbnds))
+ xbnds <-
+ switch(match.arg(xbnds),
+ panel = .xlim,
+ data = range(x, finite = TRUE))
+ if (is.character(ybnds))
+ ybnds <-
+ switch(match.arg(ybnds),
+ panel = .ylim,
+ data = range(y, finite = TRUE))
+ shape <-
+ .aspect.ratio * (diff(ybnds) / diff(.ylim)) /
+ (diff(xbnds) / diff(.xlim))
+ if (!missing(check.erosion))
+ warning("explicit 'check.erosion' specification ignored")
+ h <-hexbin(x = x, y = y,
+ xbins = xbins, shape = shape,
+ xbnds = xbnds, ybnds = ybnds,IDs=TRUE)
+
+ if (.prelim)
+ return(max(h at count))
+
+ ## have to do this because grid.hexagons croaks with unrecognized
+ ## arguments:
+ args <- list(dat = h, check.erosion = FALSE, ...)
+ keep <- names(args) %in% names(formals(grid.hexagons))
+ if ('hg' %in% type) panel.hexgrid(h)
+ if ('g' %in% type) panel.grid(h = -1, v = -1)
+ if(shadow) {
+ eh <- erode(h,cdfcut=shadow)
+ h.xy <- hcell2xy(eh,check.erosion=TRUE)
+ dx <- (0.5 * diff(eh at xbnds))/eh at xbins
+ dy <- (0.5 * diff(eh at ybnds))/(eh at xbins * h at shape * sqrt(3))
+ hexC <- hexcoords(dx, dy, sep = NULL)
+ hexpolygon(h.xy$x,h.xy$y, hexC, density = density,
+ fill = NA, border = gray(.75))
+ }
+ eh <- erode(h,cdfcut=cdfcut)
+ h.xy <- hcell2xy(eh,check.erosion=TRUE)
+ dx <- (0.5 * diff(eh at xbnds))/eh at xbins
+ dy <- (0.5 * diff(eh at ybnds))/(eh at xbins * h at shape * sqrt(3))
+ hexC <- hexcoords(dx, dy, sep = NULL)
+ hexpolygon(h.xy$x,h.xy$y, hexC, density = density,
+ fill = "green", border = gray(.75))
+ med <- which.max(eh at erode)
+ xnew <- h.xy$x[med]
+ ynew <- h.xy$y[med]
+ hexpolygon(xnew, ynew, hexC, density = density,
+ fill = "red", border =gray(.25))
+ invisible()
+}
+
+panel.hexpose <-
+ function(x, y, groups, subscripts,
+ xbins = 30,
+ xbnds = c("data", "panel"), # was: xbnds = c("panel", "data"),
+ ybnds = c("data", "panel"), # was: ybnds = c("panel", "data"),
+
+ ## special args
+ .prelim = FALSE,
+ .cpl = current.panel.limits(),
+ .xlim = .cpl$xlim,
+ .ylim = .cpl$ylim,
+ .aspect.ratio = 1,
+ #erode Args
+ cdfcut=.05,
+ #hdiff Args
+ hexpose.focus=c(1,2),
+ hexpose.focus.colors=c("yellow","blue"),
+ hexpose.focus.border=c("cyan","orange"),
+ hexpose.median.color="red",
+ hexpose.median.border="black",
+ arrows = TRUE,
+ size = unit(0.1, "inches"),
+ arrow.lwd = 2,
+ eps = 1e-6,
+ type = character(0),
+ ...,
+ check.erosion = TRUE)
+{
+ if (is.character(xbnds))
+ xbnds <-
+ switch(match.arg(xbnds),
+ panel = .xlim,
+ data = range(x, finite = TRUE))
+ if (is.character(ybnds))
+ ybnds <-
+ switch(match.arg(ybnds),
+ panel = .ylim,
+ data = range(y, finite = TRUE))
+ shape <-
+ .aspect.ratio * (diff(ybnds) / diff(.ylim)) /
+ (diff(xbnds) / diff(.xlim))
+ if (is.numeric(groups)) groups <- as.character(groups[subscripts])
+ else groups <- groups[subscripts]
+ binL <- hexList(x, y, given=groups, xbins=xbins, shape=shape,
+ xbnds=xbnds, ybnds=ybnds)
+ if ('hs' %in% type) lapply(binL at hbins,smooth.hexbin)
+ binL at hbins <- lapply(binL at hbins,erode,cdfcut=cdfcut)
+ if ('hg' %in% type) panel.hexgrid(binL at hbins[[1]]) ## ???
+ if ('g' %in% type) panel.grid(h = -1, v = -1)
+ eroded <- unlist(lapply(binL at hbins, is, "erodebin"))
+ tmph.xy <- lapply(binL at hbins, hcell2xy, check.erosion = TRUE)
+
+ ##__________________ Construct hexagon___________________
+ dx <- (0.5 * diff(binL at Xbnds))/xbins
+ dy <- (0.5 * diff(binL at Ybnds))/(xbins * binL at Shape * sqrt(3))
+ hexC <- hexcoords(dx = dx, dy = dy)
+
+ ##__________________ Set up intersections and colors___________________
+ ## Reorder so that the focus bin objects are at the top of the list
+ if(length(hexpose.focus) < binL at n) {
+ binL at hbins <- c(binL at hbins[hexpose.focus], binL at hbins[-hexpose.focus])
+ binL at Bnames <- c(binL at Bnames[hexpose.focus], binL at Bnames[-hexpose.focus])
+ }
+ cell.stat <- all.intersect(binL at hbins)
+ cell.stat.n <- apply(cell.stat, 1, sum)
+ i.depth <- max(cell.stat.n)
+
+ diff.cols <- vector(mode = "list", length = i.depth)
+ levcells <- which(cell.stat.n == 1)
+ whichbin <- apply(cell.stat[levcells, ], 1, which)
+ ## Set all the focal colors for the unique bin cells
+ ## if not specified make them equally spaced on the color wheel
+ ## with high saturation and set the background bins to gray
+ nfcol <- length(hexpose.focus)
+ nhb <- binL at n
+ nbcol <- nhb-nfcol
+ fills <-
+ if(is.null(hexpose.focus.colors)) {
+ if(nbcol > 0)
+ hsv(h = c(seq(0, 1, length = nfcol+1)[1:nfcol],rep(0, nbcol)),
+ s = c(rep(1, nfcol), rep(0, nbcol)),
+ ## V = c(rep(1, nfcol), seq(.9, .1, length=nbcol))
+ v = c(rep(1, nfcol), rep(.9, nbcol)))
+ else hsv(h=seq(0, 1, length = nhb+1))[1:nfcol]
+ }
+ else {
+ foc.col <- t(col2rgb(hexpose.focus.colors))/255
+ if(nbcol > 0) {
+ bcol <- t(col2rgb(rep(grey(.6),nbcol)))/255
+ rbind(foc.col, bcol)
+ }
+ else foc.col
+ }
+ diff.cols[[1]] <- list(fill = fills, border = gray(.8))
+
+ ##_______________ Full Cell Plotting for Unique BinL Cells_________________
+
+ if(length(levcells) > 0) {
+ for(i in unique(whichbin)) {
+ pcells <-
+ if(eroded[i])
+ binL at hbins[[i]]@cell[binL at hbins[[i]]@eroded]
+ else binL at hbins[[i]]@cell
+ pcells <- which(pcells %in% levcells[whichbin == i])
+
+ hexpolygon(x = tmph.xy[[i]]$x[pcells],
+ y = tmph.xy[[i]]$y[pcells], hexC,
+ border = hexpose.focus.border[i] ,
+ fill = hexpose.focus.colors[i] )
+ }
+ }
+
+ ## Now do the intersections. All intersections are convex
+ ## combinations of the colors of the overlapping unique bins in
+ ## the CIEluv colorspace. so if the binlist is of length 2 and
+ ## the focal hbins are "blue" and "yellow" respectively the
+ ## intersection would be green. First I need to get this to work
+ ## and then I can think about how to override this with an option
+ ## in color.control. -NL
+
+ if(i.depth > 1) {
+ for(dl in 2:(i.depth)) {
+ levcells <- which(cell.stat.n == dl)
+ if(length(levcells) == 0) next
+
+ whichbin <- apply(cell.stat[levcells, ], 1,
+ function(x)paste(which(x), sep = "", collapse = ":"))
+ inter.nm <- unique(whichbin)
+ fills <- matrix(0, length(inter.nm), 3)
+ i <- 1
+ for(bn in inter.nm) {
+ who <- as.integer(unlist(strsplit(bn, ":")))
+ ## FIXME (DS): this doesn't work
+ fills[i, ] <- mixcolors2(1/length(who),
+ diff.cols[[1]]$fill[who,])
+ i <- i+1
+ }
+ fills <- rgb(fills[,1],fills[,2],fills[,3])
+ diff.cols[[dl]] <- list(fill = fills,
+ border = gray((i.depth-dl)/i.depth))
+ ##____Full Cell Plotting for Intersecting Cells at Intersection Depth i____
+ i <- 1
+ for(ints in inter.nm) {
+ bin.i <- as.integer(unlist(strsplit(ints, ":"))[1])
+ pcells <-
+ if(eroded[bin.i])
+ binL at hbins[[bin.i]]@cell[binL at hbins[[bin.i]]@eroded]
+ else binL at hbins[[bin.i]]@cell
+ pcells <- which(pcells %in% levcells[whichbin == ints])
+ hexpolygon(x = tmph.xy[[bin.i]]$x[pcells],
+ y = tmph.xy[[bin.i]]$y[pcells], hexC,
+ border = diff.cols[[dl]]$border ,
+ fill = diff.cols[[dl]]$fill[i] )
+ i <- i+1
+ }
+ }
+ }
+
+ if(any(eroded)) {
+ hmeds <- matrix(unlist(lapply(binL at hbins[eroded],
+ function(x)unlist(getHMedian(x)))),
+ ncol = 2, byrow = TRUE)
+ hexpolygon(x = hmeds[, 1], y = hmeds[, 2], hexC,
+ border = hexpose.median.border,
+ fill = hexpose.median.color)
+ if(arrows) {
+ for(i in hexpose.focus) {
+ for(j in hexpose.focus[hexpose.focus < i]) {
+ if(abs(hmeds[i, 1] - hmeds[j, 1]) +
+ abs(hmeds[i, 2] - hmeds[j, 2]) > eps)
+ grid.arrows(c(hmeds[i, 1], hmeds[j, 1]),
+ c(hmeds[i, 2], hmeds[j, 2]),
+ default.units = "native",
+ length = size, gp = gpar(lwd = arrow.lwd))
+ }
+ }
+ }
+ }
+ invisible()
+}
+
+
+hexbinplot <- function(x, data, ...) UseMethod("hexbinplot")
+
+
+hexbinplot.formula <-
+ function(x, data = NULL,
+ prepanel = prepanel.hexbinplot,
+ panel = panel.hexbinplot,
+ groups = NULL,
+ aspect = "xy",
+ trans = NULL,
+ inv = NULL,
+ colorkey = TRUE,
+ ...,
+ maxcnt,
+ legend = NULL,
+ legend.width = TRUE,
+ subset = TRUE)
+{
+ ocall <- sys.call(sys.parent())
+ ocall[[1]] <- quote(hexbinplot)
+ ccall <- match.call()
+ if (is.logical(legend.width)) legend.width <- 1.2 * as.numeric(legend.width)
+ if (is.character(aspect) && aspect == "fill")
+ stop("aspect = 'fill' not permitted")
+ if (!is.null(trans) && is.null(inv))
+ stop("Must supply the inverse transformation 'inv'")
+ ccall$data <- data
+ ccall$prepanel <- prepanel
+ ccall$panel <- panel
+ ccall$aspect <- aspect
+ ccall$trans <- trans
+ ccall$inv <- inv
+ ccall$legend <- legend
+ ccall[[1]] <- quote(lattice::xyplot)
+ ans <- eval(ccall, parent.frame())
+
+ ## panel needs to know aspect ratio to calculate shape
+ ans <- update(ans, .aspect.ratio = ans$aspect.ratio)
+
+ ## also need maxcnt, o.w. can't draw legend, panels not comparable
+ ## either
+ if (missing(maxcnt))
+ maxcnt <-
+ max(mapply(panel.hexbinplot, ## note: not 'panel'
+ x = lapply(ans$panel.args, "[[", "x"),
+ y = lapply(ans$panel.args, "[[", "y"),
+ .xlim =
+ if (is.list(ans$x.limits)) ans$x.limits
+ else rep(list(ans$x.limits), length(ans$panel.args)),
+ .ylim =
+ if (is.list(ans$y.limits)) ans$y.limits
+ else rep(list(ans$y.limits), length(ans$panel.args)),
+ MoreArgs =
+ c(ans$panel.args.common,
+ list(.prelim = TRUE, .cpl = NA))))
+ ans <- update(ans, maxcnt = maxcnt)
+ if (colorkey)
+ ans <-
+ update(ans,
+ legend = updateList(ans$legend,
+ list(right =
+ list(fun = hexlegendGrob,
+ args =
+ list(maxcnt = maxcnt,
+ trans = trans,
+ inv = inv,
+ legend = legend.width,
+ ...)))))
+ ans$call <- ocall
+ ans
+}
+
+
+
+old.hexbinplot.formula <-
+ function(x, data = parent.frame(),
+ prepanel = prepanel.hexbinplot,
+ panel = if (is.null(groups)) panel.hexbinplot
+ else panel.hexpose,
+ groups=NULL,
+ aspect = "xy",
+ trans = NULL,
+ inv = NULL,
+ colorkey = TRUE,
+ ...,
+ maxcnt,
+ legend = NULL,
+ legend.width = TRUE)
+{
+ if (is.logical(legend.width))
+ legend.width <- 1.2 * as.numeric(legend.width)
+ if (is.character(aspect) && aspect == "fill")
+ stop("aspect = 'fill' not permitted")
+ if (!is.null(trans) && is.null(inv))
+ stop("Must supply the inverse transformation 'inv'")
+ groups <- eval(substitute(groups), data, parent.frame())
+ ## There must be a better way to handle this, ugh.
+ ans <-
+ if(is.null(groups))
+ {
+ xyplot(x, data = data,
+ prepanel = prepanel,
+ panel = panel,
+ aspect = aspect,
+ trans = trans,
+ inv = inv,
+ legend = legend,
+ ...)
+ }
+ else
+ {
+ xyplot(x, data = data,
+ prepanel = prepanel,
+ panel = panel,
+ groups=groups,
+ aspect = aspect,
+ trans = trans,
+ inv = inv,
+ legend = legend,
+ ...)
+ }
+ ## panel needs to know aspect ratio to calculate shape
+ ans <- update(ans, .aspect.ratio = ans$aspect.ratio)
+
+ ## also need maxcnt, o.w. can't draw legend, panels not comparable
+ ## either
+ if (missing(maxcnt))
+ maxcnt <-
+ max(mapply(panel.hexbinplot, ## note: not 'panel'
+ x = lapply(ans$panel.args, "[[", "x"),
+ y = lapply(ans$panel.args, "[[", "y"),
+ .xlim =
+ if (is.list(ans$x.limits)) ans$x.limits
+ else rep(list(ans$x.limits), length(ans$panel.args)),
+ .ylim =
+ if (is.list(ans$y.limits)) ans$y.limits
+ else rep(list(ans$y.limits), length(ans$panel.args)),
+ MoreArgs =
+ c(ans$panel.args.common,
+ list(.prelim = TRUE, .cpl = NA))))
+ ans <- update(ans, maxcnt = maxcnt)
+ if (colorkey)
+ ans <-
+ update(ans,
+ legend = updateList(ans$legend,
+ list(right =
+ list(fun = hexlegendGrob,
+ args =
+ list(maxcnt = maxcnt,
+ trans = trans,
+ inv = inv,
+ legend = legend.width,
+ ...)))))
+ ans
+}
+
+
+## want a grob instead of actual plotting
+
+hexlegendGrob <-
+ function(legend = 1.2,
+ inner = legend / 5,
+ cex.labels = 1,
+ cex.title = 1.2,
+ style = "colorscale",
+ minarea = 0.05, maxarea = 0.8,
+ mincnt = 1, maxcnt,
+ trans = NULL, inv = NULL,
+ colorcut = seq(0, 1, length = 17),
+ density = NULL, border = NULL, pen = NULL,
+ colramp = function(n) { LinGray(n,beg = 90,end = 15) },
+ ...,
+ vp = NULL,
+ draw = FALSE)
+{
+ ## the formal arg matching should happen
+ style <- match.arg(style, eval(formals(grid.hexagons)[["style"]]))
+ if (style %in% c("centroids", "lattice", "colorscale")) {
+ ## _______________tranformations_______________________
+ if(is.null(trans))
+ {
+ sc <- maxcnt - mincnt
+ bnds <- round(mincnt + sc * colorcut)
+ }
+ else
+ {
+ if(!is.function(trans) && !is.function(inv))
+ stop("'trans' and 'inv' must both be functions if 'trans' is not NULL")
+ con <- trans(mincnt)
+ sc <- trans(maxcnt) - con
+ bnds <- round(inv(con + sc * colorcut))
+ }
+ }
+
+ ## grob
+ ans <-
+ switch(style,
+ "colorscale" = {
+
+ n <- length(bnds)
+ pen <- colramp(n-1)
+
+ ## rectangles instead of polygons
+ ## pol <-
+ ## rectGrob(x = 0.5, y = 1:(n-1)/n,
+ ## height = 1/n,
+ ## default.units = "npc",
+ ## gp = gpar(fill = pen, col = border))
+
+ hexxy <- hexcoords(dx = 1, n = 1)[c("x", "y")]
+ maxxy <- max(abs(unlist(hexxy)))
+ hexxy <- lapply(hexxy, function(x) 0.5 * x/ maxxy)
+
+ pol <-
+ polygonGrob(x = 0.5 + rep(hexxy$x, n-1),
+ y = (rep(1:(n-1), each = 6) + hexxy$y) / n,
+ id.lengths = rep(6, n-1),
+ gp = gpar(fill = pen, col = border),
+ default.units = "npc")
+ txt <-
+ textGrob(as.character(bnds),
+ x = 0.5,
+ y = (0:(n-1) + 0.5) / n,
+ gp = gpar(cex = cex.labels),
+ default.units = "npc")
+ ttl <- textGrob("Counts", gp = gpar(cex = cex.title))
+
+ key.layout <-
+ grid.layout(nrow = 2, ncol = 2,
+ heights =
+ unit(c(1.5, 1),
+ c("grobheight", "grobheight"),
+ data = list(ttl, txt)),
+ widths =
+ unit(c(1/n, 1),
+ c("grobheight", "grobwidth"),
+ data = list(pol, txt)),
+ respect = TRUE)
+ key.gf <- frameGrob(layout = key.layout, vp = vp)
+ key.gf <- placeGrob(key.gf, ttl, row = 1, col = 1:2)
+ key.gf <- placeGrob(key.gf, pol, row = 2, col = 1)
+ key.gf <- placeGrob(key.gf, txt, row = 2, col = 2)
+ key.gf
+ },
+ "centroids" = ,
+ "lattice" = {
+ warning("legend shows relative sizes")
+
+ ## Note: it may not be impossible to get absolute
+ ## sizes. The bigger problem is that when
+ ## [xy]bnds="data", the sizes (for the same count) may
+ ## not be the same across panels. IMO, that's a more
+ ## useful feature than getting the absolute sizes
+ ## right.
+
+ radius <- sqrt(minarea + (maxarea - minarea) * colorcut)
+ n <- length(radius)
+ if(is.null(pen)) pen <- 1
+ if(is.null(border)) border <- pen
+
+ hexxy <- hexcoords(dx = 1, n = 1)[c("x", "y")]
+ maxxy <- max(abs(unlist(hexxy)))
+ hexxy <- lapply(hexxy, function(x) 0.5 * x/ maxxy)
+
+ pol <-
+ polygonGrob(x = 0.5 + rep(radius, each = 6) * rep(hexxy$x, n),
+ y = (rep(0.5 + 1:n, each = 6) +
+ rep(radius, each = 6) * hexxy$y - 1) / n,
+ id.lengths = rep(6, n),
+ gp = gpar(fill = pen, col = border),
+ default.units = "npc")
+ txt <-
+ textGrob(as.character(bnds),
+ x = 0.5,
+ y = (1:n - 0.5) / n,
+ gp = gpar(cex = cex.labels),
+ default.units = "npc")
+ ttl <- textGrob("Counts", gp = gpar(cex = cex.title))
+
+ key.layout <-
+ grid.layout(nrow = 2, ncol = 2,
+ heights =
+ unit(c(1.5, 1),
+ c("grobheight", "grobheight"),
+ data = list(ttl, txt)),
+ widths =
+ unit(c(1/n, 1),
+ c("grobheight", "grobwidth"),
+ data = list(pol, txt)),
+ respect = TRUE)
+ key.gf <- frameGrob(layout = key.layout, vp = vp)
+
+ key.gf <- placeGrob(key.gf, ttl, row = 1, col = 1:2)
+ key.gf <- placeGrob(key.gf, pol, row = 2, col = 1)
+ key.gf <- placeGrob(key.gf, txt, row = 2, col = 2)
+ key.gf
+ },
+ "nested.lattice" = ,
+ "nested.centroids" = {
+ dx <- inner/2
+ dy <- dx/sqrt(3)
+ hexC <- hexcoords(dx, dy, n = 1, sep = NULL)
+
+ ## _____________x scaling_____________________________
+ numb <- cut(floor(legend/inner), breaks = c(-1, 0, 2,4))
+ ## Note: In old code
+ ## top breaks=c(-1,0,2,4,8), numb<- 5 and size=1:9
+ if (is.na(numb)) numb <- 4
+ switch(numb,
+ {
+ warning("not enough space for legend")
+ return(textGrob(""))
+ },
+ size <- 5,
+ size <- c(1, 5, 9),
+ size <- c(1, 3, 5, 7, 9))
+ xmax <- length(size)
+ radius <- sqrt(minarea + (maxarea - minarea) * (size - 1)/9)
+ txt <- as.character(size)
+ ##___________________y scaling_____________________
+ lab <- c("Ones", "Tens", "Hundreds",
+ "Thousands", "10 Thousands", "100 Thousands",
+ "Millions", "10 Millions",
+ "100 Millions", "Billions")
+ power <- floor(log10(maxcnt)) + 1
+ yinc <- 16 * dy
+ ysize <- yinc * power
+ xmid <- 0
+ x <- inner * (1:xmax - (1 + xmax)/2) + xmid
+ n <- length(x)
+ tx <- rep.int(hexC$x, n)
+ ty <- rep.int(hexC$y, n)
+ six <- rep.int(6:6, n)
+ ## y <- rep.int(3 * dy - yinc, xmax)
+ y <- rep.int(3 * dy - 0.75 * yinc, xmax)
+
+ if (is.null(pen)) {
+ pen <- 1:power +1
+ pen <- cbind(pen, pen +10)
+ }
+ if (is.null(border)) border <- TRUE
+
+ key.layout <-
+ grid.layout(nrow = 1, ncol = 1,
+ heights = unit(ysize, "inches"),
+ widths = unit(legend, "inches"),
+ respect = TRUE)
+ key.gf <- frameGrob(layout = key.layout, vp = vp)
+
+ ## for debugging
+ ## key.gf <-
+ ## placeGrob(key.gf, rectGrob(gp = gpar(fill = "transparent")))
+
+ n6 <- rep.int(6, n)
+ for(i in 1:power) {
+ y <- y + yinc
+ key.gf <-
+ placeGrob(key.gf,
+ polygonGrob(x = unit(legend / 2 + rep.int(hexC$x, n) + rep.int(x, n6), "inches"),
+ y = unit(rep.int(hexC$y, n) + rep.int(y, n6), "inches"),
+ id.lengths = n6,
+ gp =
+ gpar(col = pen[i, 1],
+ fill = if (border) 1 else pen[i, 1])),
+ row = 1, col = 1)
+
+ key.gf <-
+ placeGrob(key.gf,
+ polygonGrob(x = legend / 2 + tx * rep.int(radius, six) + rep.int(x, six),
+ y = ty * rep.int(radius, six) + rep.int(y, six),
+ default.units = "inches", id=NULL,
+ id.lengths=rep(6,n),
+ gp = gpar(fill = pen[i,2], col = border)),
+ row = 1, col = 1)
+
+ key.gf <-
+ placeGrob(key.gf,
+ textGrob(txt,
+ x = legend / 2 + x,
+ y = y - 4.5 * dy,
+ default.units = "inches",
+ gp = gpar(cex = cex.labels)),
+ row = 1, col = 1)
+ key.gf <-
+ placeGrob(key.gf,
+ textGrob(lab[i],
+ x = legend / 2 + xmid,
+ y = y[1] + 4.5 * dy,
+ default.units = "inches",
+ gp = gpar(cex = 1.3 * cex.title)),
+ row = 1, col = 1)
+ }
+ key.gf
+ })
+ if (draw)
+ {
+ grid.draw(ans)
+ invisible(ans)
+ }
+ else ans
+}
diff --git a/R/hexpanel.R b/R/hexpanel.R
new file mode 100644
index 0000000..a0d9f15
--- /dev/null
+++ b/R/hexpanel.R
@@ -0,0 +1,37 @@
+panel.hexloess <-
+function(bin, w=NULL, span = 2/3, degree = 1, family = c("symmetric",
+ "gaussian"), evaluation = 50, lwd = add.line$lwd, lty = add.line$lty,
+ col, col.line = add.line$col, ...)
+{
+ stop("panel.hexloess is no longer available")
+ add.line <- trellis.par.get("add.line")
+
+## x <- bin at xcm
+## y <- bin at ycm
+## if(is.null(w))w <- bin at count
+## control <- loess.control(...)
+## notna <- !(is.na(x) | is.na(y))
+## new.x <- seq(min(x[notna]), max(x[notna]), length = evaluation)
+## family <- match.arg(family)
+## iterations <- if (family == "gaussian") 1 else control$iterations
+## fit <- stats:::simpleLoess(y, x, w, span, degree, FALSE, FALSE,
+## normalize = FALSE, "none", "interpolate",
+## control$cell, iterations, control$trace.hat)
+## kd <- fit$kd
+## z <- .C("loess_ifit", as.integer(kd$parameter), as.integer(kd$a),
+## as.double(kd$xi), as.double(kd$vert), as.double(kd$vval),
+## as.integer(evaluation), as.double(x), fit = double(evaluation),
+## PACKAGE = "stats")$fit
+## if (length(x) > 0) {
+## if (!missing(col) && missing(col.line)) {
+## col.line <- col
+## }
+## add.line <- trellis.par.get("add.line")
+## panel.lines(new.x, z, col = col.line, lty = lty, lwd = lwd)
+## }
+}
+
+panel.hexgrid <- function(h, border=grey(.85))
+{
+ hexGraphPaper(h,border=border)
+}
diff --git a/R/hexplom.R b/R/hexplom.R
new file mode 100644
index 0000000..fdf8f6a
--- /dev/null
+++ b/R/hexplom.R
@@ -0,0 +1,352 @@
+panel.hexplom <-
+ function(...)
+ panel.hexbinplot(...)
+
+
+hexplom <- function(x, data, ...)
+{
+ UseMethod("hexplom")
+}
+
+
+
+
+
+hexplom.data.frame <-
+ function (x, data = NULL, ..., groups = NULL, subset = TRUE)
+{
+ ocall <- sys.call(sys.parent())
+ ocall[[1]] <- quote(hexplom)
+ ccall <- match.call()
+ if (!is.null(ccall$data))
+ warning("explicit 'data' specification ignored")
+ ccall$data <- list(x = x, groups = groups, subset = subset)
+ ccall$x <- ~x
+ ccall$groups <- groups
+ ccall$subset <- subset
+ ccall[[1]] <- quote(hexbin::hexplom)
+ ans <- eval.parent(ccall)
+ ans$call <- ocall
+ ans
+}
+
+hexplom.matrix <-
+ function (x, data = NULL, ..., groups = NULL, subset = TRUE)
+{
+ ocall <- sys.call(sys.parent())
+ ocall[[1]] <- quote(hexplom)
+ ccall <- match.call()
+ if (!is.null(ccall$data))
+ warning("explicit 'data' specification ignored")
+ ccall$data <- list(x = x, groups = groups, subset = subset)
+ ccall$x <- ~x
+ ccall$groups <- groups
+ ccall$subset <- subset
+ ccall[[1]] <- quote(hexbin::hexplom)
+ ans <- eval.parent(ccall)
+ ans$call <- ocall
+ ans
+}
+
+
+hexplom.formula <-
+ function(x, data = NULL, ...)
+{
+ ocall <- sys.call(sys.parent())
+ ocall[[1]] <- quote(hexplom)
+ ccall <- match.call()
+ ccall[[1]] <- quote(lattice::splom)
+ if (is.null(ccall$panel)) ccall$panel <- panel.hexplom
+ ans <- eval.parent(ccall)
+ ans$call <- ocall
+ ans
+}
+
+
+
+
+old.hexplom.formula <-
+ function(x,
+ data = parent.frame(),
+ auto.key = FALSE,
+ aspect = 1,
+ between = list(x = 0.5, y = 0.5),
+ #panel = if (is.null(groups)) "panel.hexplom"
+ #else "panel.superpose",
+ panel = panel.hexplom,
+ prepanel = NULL,
+ scales = list(),
+ strip = TRUE,
+ groups = NULL,
+ xlab = "Scatter Plot Matrix",
+ xlim,
+ ylab = NULL,
+ ylim,
+ superpanel = "panel.pairs",
+ pscales = 5,
+ varnames,
+ drop.unused.levels = lattice.getOption("drop.unused.levels"),
+ ...,
+ default.scales = list(draw = FALSE, relation = "same", axs = "i"),
+ subset = TRUE)
+{
+ ## dots <- eval(substitute(list(...)), data, parent.frame())
+ dots <- list(...)
+
+ #groups <- eval(substitute(groups), data, parent.frame())
+ if(!is.null(groups))stop("groups not implemented yet")
+ subset <- eval(substitute(subset), data, parent.frame())
+
+ ## Step 1: Evaluate x, y, etc. and do some preprocessing
+
+ ## right.name <- deparse(substitute(formula))
+ ## formula <- eval(substitute(formula), data, parent.frame())
+ form <-
+ ## if (inherits(formula, "formula"))
+ latticeParseFormula(x, data,
+ subset = subset, groups = groups,
+ multiple = FALSE,
+ outer = FALSE, subscripts = TRUE,
+ drop = drop.unused.levels)
+## else {
+## if (is.matrix(formula)) {
+## list(left = NULL,
+## right = as.data.frame(formula)[subset,],
+## condition = NULL,
+## left.name = "",
+## right.name = right.name,
+## groups = groups,
+## subscr = seq(length = nrow(formula))[subset])
+## }
+## else if (is.data.frame(formula)) {
+## list(left = NULL,
+## right = formula[subset,],
+## condition = NULL,
+## left.name = "",
+## right.name = right.name,
+## groups = groups,
+## subscr = seq(length = nrow(formula))[subset])
+## }
+## else stop("invalid formula")
+## }
+
+
+ ## We need to be careful with subscripts here. It HAS to be there,
+ ## and it's to be used to index x, y, z (and not only groups,
+ ## unlike in xyplot etc). This means we have to subset groups as
+ ## well, which is about the only use for the subscripts calculated
+ ## in latticeParseFormula, after which subscripts is regenerated
+ ## as a straight sequence indexing the variables
+
+ if (!is.null(form$groups)) groups <- form$groups[form$subscr]
+ subscr <- seq(length = nrow(form$right))
+
+ if (!is.function(panel)) panel <- eval(panel)
+ if (!is.function(strip)) strip <- eval(strip)
+
+ prepanel <-
+ if (is.function(prepanel)) prepanel
+ else if (is.character(prepanel)) get(prepanel)
+ else eval(prepanel)
+
+ cond <- form$condition
+ number.of.cond <- length(cond)
+ x <- as.data.frame(form$right)
+
+ if (number.of.cond == 0) {
+ strip <- FALSE
+ cond <- list(as.factor(rep(1, nrow(x))))
+ number.of.cond <- 1
+ }
+
+ if (!missing(varnames)) colnames(x) <-
+ eval(substitute(varnames), data, parent.frame())
+
+ ## create a skeleton trellis object with the
+ ## less complicated components:
+
+ #foo <- do.call(lattice:::trellis.skeleton,
+ foo <- do.call(trellis.skeleton,
+ c(list(cond = cond,
+ aspect = aspect,
+ between = between,
+ panel = superpanel,
+ strip = strip,
+ xlab = xlab,
+ ylab = ylab,
+ xlab.default = "Scatter Plot Matrix"), dots))
+
+ dots <- foo$dots # arguments not processed by trellis.skeleton
+ foo <- foo$foo
+ foo$call <- match.call()
+
+ ## Step 2: Compute scales.common (leaving out limits for now)
+
+ ## FIXME: It is not very clear exactly what effect scales is
+ ## supposed to have. Not much in Trellis (probably), but there are
+ ## certain components which are definitely relevant, and certain
+ ## others (like log) which can be used in innovative
+ ## ways. However, I'm postponing all that to later, if at all
+
+ if (!is.list(scales)) scales <- list()
+
+ ## some defaults for scales
+
+# if (is.null(scales$draw)) scales$draw <- FALSE
+# if (is.null(scales$relation)) scales$relation <- "same"
+# if (is.null(scales$axs)) scales$axs <- "i"
+
+ scales <- updateList(default.scales, scales)
+ foo <- c(foo,
+ #do.call(lattice:::construct.scales, scales))
+ do.call(construct.scales, scales))
+
+
+ ## Step 3: Decide if limits were specified in call:
+
+ have.xlim <- !missing(xlim)
+ if (!is.null(foo$x.scales$limit)) {
+ have.xlim <- TRUE
+ xlim <- foo$x.scales$limit
+ }
+ have.ylim <- !missing(ylim)
+ if (!is.null(foo$y.scales$limit)) {
+ have.ylim <- TRUE
+ ylim <- foo$y.scales$limit
+ }
+
+ ## Step 4: Decide if log scales are being used (has to be NO):
+
+ have.xlog <- !is.logical(foo$x.scales$log) || foo$x.scales$log
+ have.ylog <- !is.logical(foo$y.scales$log) || foo$y.scales$log
+
+ ## immaterial, since scales has no effect.
+
+# if (have.xlog) {
+# xlog <- foo$x.scales$log
+# xbase <-
+# if (is.logical(xlog)) 10
+# else if (is.numeric(xlog)) xlog
+# else if (xlog == "e") exp(1)
+#
+# x <- log(x, xbase)
+# if (have.xlim) xlim <- log(xlim, xbase)
+# }
+# if (have.ylog) {
+# ylog <- foo$y.scales$log
+# ybase <-
+# if (is.logical(ylog)) 10
+# else if (is.numeric(ylog)) ylog
+# else if (ylog == "e") exp(1)
+#
+# y <- log(y, ybase)
+# if (have.ylim) ylim <- log(ylim, ybase)
+# }
+
+ ## Step 5: Process cond
+
+ cond.max.level <- unlist(lapply(cond, nlevels))
+
+ ## id.na used only to see if any plotting is needed. Not used
+ ## subsequently, unlike other functions
+
+ id.na <- FALSE
+ for (j in 1:ncol(x))
+ id.na <- id.na | is.na(x[,j])
+ for (var in cond)
+ id.na <- id.na | is.na(var)
+ if (!any(!id.na)) stop("nothing to draw")
+ ## Nothing simpler ?
+
+
+ ## Step 6: Evaluate layout, panel.args.common and panel.args
+
+
+ foo$panel.args.common <-
+ c(list(z = x,
+ panel = panel,
+ panel.subscripts = TRUE,
+ groups = groups, # xscales = foo$x.scales, yscales =foo$y.scales,
+ .aspect.ratio=aspect,
+ pscales = pscales),
+ dots)
+
+ nplots <- prod(cond.max.level)
+ if (nplots != prod(sapply(foo$condlevels, length))) stop("mismatch")
+ foo$panel.args <- vector(mode = "list", length = nplots)
+
+
+ cond.current.level <- rep(1, number.of.cond)
+
+
+ for (panel.number in seq(length = nplots))
+ {
+
+ ##id <- !id.na WHY ?
+ for(i in 1:number.of.cond)
+ {
+ var <- cond[[i]]
+ id <- if (is.shingle(var))
+ ((var >=
+ levels(var)[[cond.current.level[i]]][1])
+ & (var <=
+ levels(var)[[cond.current.level[i]]][2]))
+ else (as.numeric(var) == cond.current.level[i])
+ }
+
+ foo$panel.args[[panel.number]] <-
+ list(subscripts = subscr[id])
+
+ cond.current.level <-
+ #lattice:::cupdate(cond.current.level, cond.max.level)
+ cupdate(cond.current.level, cond.max.level)
+ }
+
+
+ #more.comp <- c(lattice:::limits.and.aspect(
+ more.comp <- c(limits.and.aspect(
+ lattice::prepanel.default.splom,
+ prepanel = prepanel,
+ have.xlim = have.xlim, xlim = xlim,
+ have.ylim = have.ylim, ylim = ylim,
+ x.relation = foo$x.scales$relation,
+ y.relation = foo$y.scales$relation,
+ panel.args.common = foo$panel.args.common,
+ panel.args = foo$panel.args,
+ aspect = aspect,
+ nplots = nplots,
+ x.axs = foo$x.scales$axs,
+ y.axs = foo$y.scales$axs),
+ #lattice::: cond.orders(foo))
+ cond.orders(foo))
+ foo[names(more.comp)] <- more.comp
+
+
+
+ if (is.null(foo$legend) && !is.null(groups) &&
+ (is.list(auto.key) || (is.logical(auto.key) && auto.key)))
+ {
+ foo$legend <-
+ list(list(fun = "drawSimpleKey",
+ args =
+ updateList(list(text = levels(as.factor(groups)),
+ points = TRUE,
+ rectangles = FALSE,
+ lines = FALSE),
+ if (is.list(auto.key)) auto.key else list())))
+ foo$legend[[1]]$x <- foo$legend[[1]]$args$x
+ foo$legend[[1]]$y <- foo$legend[[1]]$args$y
+ foo$legend[[1]]$corner <- foo$legend[[1]]$args$corner
+
+ names(foo$legend) <-
+ if (any(c("x", "y", "corner") %in% names(foo$legend[[1]]$args)))
+ "inside"
+ else
+ "top"
+ if (!is.null(foo$legend[[1]]$args$space))
+ names(foo$legend) <- foo$legend[[1]]$args$space
+ }
+
+ class(foo) <- "trellis"
+ foo
+}
diff --git a/R/hexutil.R b/R/hexutil.R
new file mode 100644
index 0000000..a605481
--- /dev/null
+++ b/R/hexutil.R
@@ -0,0 +1,122 @@
+hcell2xyInt <- function(hbin, xbins=NULL, xbnds=NULL, ybnds=NULL, shape=NULL)
+{
+ if(missing(hbin) && (is.null(xbnds) || is.null(ybnds)))
+ stop("Need a hexbin object or boundaries to make lattice")
+ if(missing(hbin) && (is.null(xbins) || is.null(shape)))
+ stop("Need xbins and shape to make a lattice")
+ if(!missing(hbin)) {
+ xbins <- hbin at xbins
+ shape <- hbin at shape
+ xbnds <- if(is.null(xbnds)) hbin at xbnds else xbnds
+ ybnds <- if(is.null(ybnds)) hbin at ybnds else ybnds
+ dimen <- hbin at dimen
+
+ }
+ if(missing(hbin)) {
+ jmax <- floor(xbins + 1.5001)
+ imax <- 2 * floor((xbins *shape)/sqrt(3) + 1.5001)
+ dimen <- c(imax, jmax)
+ }
+ cell <- 1:(dimen[1]*dimen[2])-1
+ i <- cell %/% dimen[2]
+ j <- cell %% dimen[2]
+ list(i=i+1, j=j+1)
+}
+
+hgridcent <- function(xbins, xbnds, ybnds, shape, edge.add=0)
+{
+ ## auxiliary for hexGraphPaper():
+ jmax <- floor(xbins + 1.5001)
+ c1 <- 2 * floor((xbins *shape)/sqrt(3) + 1.5001)
+ imax <- (jmax*c1 -1)/jmax + 1
+ dimen <- c(imax, jmax)
+ c3 <- diff(xbnds)/xbins
+ c4 <- (diff(ybnds) * sqrt(3))/(2 * shape * xbins)
+ if(edge.add > 0) {
+ xbnds <- xbnds + 1.5*c(-edge.add*c3, edge.add*c3)
+ ybnds <- ybnds + c(-edge.add*c4, edge.add*c4)
+ dimen <- dimen + rep.int(2*edge.add, 2)
+ }
+ jmax <- dimen[2]
+ cell <- 1:(dimen[1]*dimen[2])
+ i <- cell %/% jmax
+ j <- cell %% jmax
+ y <- c4 * i + ybnds[1]
+ x <- c3 * ifelse(i %% 2 == 0, j, j + 0.5) + xbnds[1]
+ list(x = x, y = y, dimen = dimen, dx=c3, dy=c4)
+}
+
+hexGraphPaper <-
+ function(hb, xbnds=NULL, ybnds=NULL, xbins=30, shape=1,
+ add=TRUE, fill.edges=1, fill=0, border=1)
+{
+ if(missing(hb) && (is.null(xbnds) || is.null(ybnds)))
+ stop("Need a hexbin object or boundaries to make lattice")
+ if(!missing(hb)) {
+ xbins <- hb at xbins
+ shape <- hb at shape
+ xbnds <- if(is.null(xbnds)) hb at xbnds else xbnds
+ ybnds <- if(is.null(ybnds)) hb at ybnds else ybnds
+ dimen <- hb at dimen
+ }
+ xy <- hgridcent(xbins, xbnds, ybnds, shape, edge.add=fill.edges)
+ if(add){
+ sx <- xbins/diff(xbnds)
+ sy <- (xbins * shape)/diff(ybnds)
+ inner <- 0.5
+ outer <- (2 * inner)/sqrt(3)
+ dx <- inner/sx
+ dy <- outer/(2 * sy)
+ if(add){
+ hexC <- hexcoords(dx, dy, sep=NULL)
+ hexpolygon (xy$x, xy$y, hexC, dx, dy,
+ fill = fill, border = border, hUnit = "native")
+ }
+ }
+ invisible(xy)
+}
+
+hexTapply <- function(hbin,dat,FUN=sum,...,simplify=TRUE)
+{
+ if(is.null(hbin at cID))
+ stop("Must have cell ID's to do this operation \n
+ please re-bin data using IDs = TRUE")
+ if((length(dat)> 0) && (length(dat) != length(hbin at cID)))
+ stop("Length of IDs does not match the length of the data")
+ tapply(dat,hbin at cID,FUN,...,simplify=simplify)
+}
+
+optShape <- function(vp, height=NULL, width=NULL, mar=NULL)
+{
+ if(missing(vp) && (is.null(height) || is.null(width)))
+ stop("Need a viewport object or height and width of the plotting region.")
+ if(!missing(vp)) {
+ if("hexVP" %in% class(vp)) {
+ height <- vp at plt[2]
+ width <- vp at plt[1]
+ }
+ else if("viewport"%in%class(vp)) {
+ #height <- convertHeight(unit(1,"npc"),"inches")
+ #width <- convertWidth (unit(1,"npc"),"inches")
+ height <- convertUnit(vp$height,"inches")
+ width <- convertUnit(vp$width,"inches")
+ }
+ else
+ stop("need valid viewport or hexViewport")
+ }
+ if(!is.null(mar)){
+ height <- height - mar[1] - mar[3]
+ width <- width - mar[2] - mar[4]
+ }
+
+ shape <- as.numeric(height)/as.numeric(width)
+ shape
+}
+
+inout.hex <- function(hbin,mincnt)
+{
+ if(is.null(hbin at cID))
+ stop("bin object must have a cID slot, \n try re-binning with ID = TRUE")
+ tI <- table(hbin at cID)
+ which(hbin at cID%in%(names(tI)[tI<mincnt]))
+}
diff --git a/R/lattice.R b/R/lattice.R
new file mode 100644
index 0000000..bfae156
--- /dev/null
+++ b/R/lattice.R
@@ -0,0 +1,744 @@
+# the functions in this file are verbatim copies from those in package
+# lattice, http://cran.r-project.org/src/contrib/lattice_0.20-29.tar.gz
+# copied on Aug 8, 2014, by Edzer Pebesma.
+
+# reason for copying is that hexbin 1.26-3 generates
+# the following NOTE on CRAN:
+#
+# checking dependencies in R code ... NOTE
+# Unexported objects imported by ':::' calls:
+# lattice:::cond.orders lattice:::construct.scales
+# lattice:::cupdate lattice:::limits.and.aspect
+# lattice:::trellis.skeleton
+# See the note in ?::: about the use of this operator.
+# See the information on DESCRIPTION files in the chapter Creating R
+# packages of the Writing R Extensions manual.
+
+# the files in lattice carry the following copyright notice:
+
+### Copyright (C) 2001-2006 Deepayan Sarkar <Deepayan.Sarkar at R-project.org>
+### Copyright (C) 2001-2005 Saikat DebRoy <saikat at stat.wisc.edu>
+###
+### This file is part of the lattice package for R.
+### It is made available under the terms of the GNU General Public
+### License, version 2, or at your option, any later version,
+### incorporated herein by reference.
+###
+### This program is distributed in the hope that it will be
+### useful, but WITHOUT ANY WARRANTY; without even the implied
+### warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+### PURPOSE. See the GNU General Public License for more
+### details.
+###
+### You should have received a copy of the GNU General Public
+### License along with this program; if not, write to the Free
+### Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+### MA 02110-1301, USA
+
+construct.legend <-
+ function(legend = NULL, key = NULL, fun = "draw.key")
+{
+ if (is.null(legend) && is.null(key)) return(NULL)
+ if (is.null(legend)) legend <- list()
+ if (!is.null(key))
+ {
+ space <- key$space
+ x <- y <- corner <- NULL
+
+ if (is.null(space))
+ {
+ if (any(c("x", "y", "corner") %in% names(key)))
+ {
+ stopifnot(is.null(x) || (length(x) == 1 && x >= 0 && x <= 1))
+ stopifnot(is.null(y) || (length(y) == 1 && y >= 0 && y <= 1))
+ stopifnot(is.null(corner) ||
+ (length(corner) == 2 &&
+ all(corner %in% c(0, 1))))
+ space <- "inside"
+ x <- key$x
+ y <- key$y
+ corner <- key$corner
+ ## check for valid values
+ }
+ else
+ space <- "top"
+ }
+ if (space != "inside" && space %in% names(legend))
+ stop(gettextf("component '%s' duplicated in key and legend", space))
+
+ key.legend <- list(fun = fun, args = list(key = key, draw = FALSE))
+ key.legend$x <- x
+ key.legend$y <- y
+ key.legend$corner <- corner
+
+ legend <- c(list(key.legend), legend)
+ names(legend)[1] <- space
+ }
+ legend
+}
+
+extend.limits <-
+ function(lim, length = 1, axs = "r",
+ prop =
+ if (axs == "i") 0
+ else lattice.getOption("axis.padding")$numeric)
+{
+ ## if (!is.numeric(lim)) NA
+ if (all(is.na(lim))) NA_real_ # or lim?
+ else if (is.character(lim) )
+ {
+ c(1, length(lim)) + c(-1, 1) * if (axs == "i") 0.5 else lattice.getOption("axis.padding")$factor
+ }
+ else if (length(lim) == 2)
+ {
+ if (lim[1] > lim[2])
+ {
+ ccall <- match.call()
+ ccall$lim <- rev(lim)
+ ans <- eval.parent(ccall)
+ return (rev(ans))
+ }
+ if (!missing(length) && !missing(prop))
+ stop("'length' and 'prop' cannot both be specified")
+ if (length <= 0) stop("'length' must be positive")
+ if (!missing(length))
+ {
+ prop <- (as.numeric(length) - as.numeric(diff(lim))) / (2 * as.numeric(diff(lim)))
+ }
+ if (lim[1]==lim[2]) lim + 0.5 * c(-length,length)
+ else
+ {
+ d <- diff(as.numeric(lim))
+ lim + prop * d * c(-1,1)
+ }
+ }
+ else
+ {
+ print(lim)
+ stop("improper length of 'lim'")
+ }
+}
+
+limitsFromLimitlist <-
+ function(have.lim,
+ lim,
+ relation,
+ limitlist,
+ used.at,
+ numlimitlist,
+ axs,
+ npackets)
+ ## have.lim: logical, whether xlim/ylim was explicitly specified
+ ## lim: the specified limit if have.lim = TRUE
+ ## relation: same/free/sliced
+ ## limitlist: list of limits from prepanel calculations, one for each panel
+ ## numlimitlist: (optional) numeric locations for factors (lim
+ ## will be levels including unused ones)
+ ## axs: "r", "i" etc, passed on to extend.limits
+
+ ## return value depends on relation. (See limits.and.aspect below,
+ ## where this is used, for partial enlightenment.)
+{
+
+ if (relation == "same")
+ {
+ ## The problem here is that we need to figure out the overall
+ ## limit required from the limits of each panel. This could be
+ ## a problem for two reasons. First, some panels could have no
+ ## data in them, in which case the corresponding limits would
+ ## be NA. Secondly, the limits could be either numeric or
+ ## character vectors (the latter for factors). When relation =
+ ## same, the type should be same across panels. When numeric,
+ ## we just take range, leaving out NAs. But what about
+ ## factors? Is it OK to assume that all the non-NA vectors
+ ## would be exactly the same ? They should be, since levels(x)
+ ## would not change even if not all levels are
+ ## represented. So, I'm just taking unique of all the vectors
+ ## concatenated, excluding NA's
+
+ ## Additional complication: Need to preserve class of limits,
+ ## to be used later in tick location/label calculation. Not a
+ ## problem in other cases, but here unlist-ing loses the
+ ## class.
+
+
+ #if (!have.lim)
+ ## always calculate the limits from prepanel first:
+
+ ## should check that all classes are the same. How ? What
+ ## about NA's ? Arrgh!
+
+ ## to handle NA's, how about:
+
+ all.na <- unlist(lapply(limitlist, function(x) all(is.na(x))))
+ class.lim <- ## retain non-NA limitlists only
+ lapply(limitlist[!all.na], class)
+ ## class.lim is a list now, may be length 0
+ limits <- unlist(limitlist) ## loses the class attribute
+
+ ## if (length(limits) > 0)
+ if (sum(!is.na(limits)) > 0)
+ {
+ if (is.character(limits))
+ {
+ limits <- unique(limits[!is.na(limits)])
+ slicelen <- diff(extend.limits(limits, axs = axs))
+ }
+ else ## if (is.numeric(limits)) # or dates etc
+ {
+ limits <-
+ extend.limits(range(as.numeric(limits), finite = TRUE),
+ axs = axs)
+ slicelen <- diff(range(limits, finite = TRUE))
+ }
+
+ ## hopefully put back appropriate class of limits:
+ ## FIXME: date changes may have messed this up
+
+ if (length(class.lim) > 0)
+ class(limits) <-
+ if (all(class.lim[[1]] == "integer"))
+ "numeric" else class.lim[[1]]
+
+ ## (have to handle "integer" specially, since variable
+ ## specifications like 1:10 are rather common, and
+ ## class() <- "integer" would turn the limits into
+ ## integers)
+ }
+ else
+ {
+ limits <- c(0,1)
+ slicelen <- 1
+ }
+
+ if (have.lim)
+ {
+ if (is.list(lim))
+ stop("limits cannot be a list when relation = same")
+ old.limits <- limits
+ limits <- lim
+ ## lim overrides prepanel except NAs
+ if (!is.character(limits) && !is.character(old.limits)) {
+ limits[is.na(limits)] <- old.limits[is.na(limits)]
+ }
+ slicelen <-
+ ## this no longer works for dates (R 2.6)
+## if (is.numeric(lim)) diff(range(lim))
+## else length(lim) + 2
+ if (is.character(limits)) length(limits) + 2
+ else diff(range(as.numeric(limits)))
+ }
+ ans <- list(limits = limits, slicelen = slicelen)
+ }
+ else if (relation == "sliced")
+ {
+ if (have.lim)
+ {
+ if (is.list(lim))
+ {
+ limits <- rep(lim, length.out = npackets)
+ }
+ else warning("Explicitly specified limits ignored")
+ }
+ slicelen <- limitlist
+ for (i in seq_along(limitlist))
+ {
+ slicelen[[i]] <-
+ ## if (is.numeric(limitlist[[i]]))
+ if (!is.character(limitlist[[i]]))
+ {
+ if (any(is.finite(limitlist[[i]])))
+ ## range unnecessary, but...
+ diff(range(as.numeric(limitlist[[i]]), finite = TRUE))
+ else NA_real_
+ }
+ else if (!any(is.na(numlimitlist[[i]])))
+ diff(range(as.numeric(numlimitlist[[i]])))
+ else NA_real_
+ }
+ slicelen <-
+ (if (axs == "i") 1 else 1 + 2 * lattice.getOption("axis.padding")$numeric) *
+ max(unlist(slicelen), na.rm = TRUE)
+ for (i in seq_along(limitlist))
+ {
+ if (is.numeric(limitlist[[i]]))
+ limitlist[[i]] <-
+ extend.limits(limitlist[[i]], length = slicelen)
+ }
+ for (i in seq_along(numlimitlist))
+ {
+ if (!all(is.na(numlimitlist[[i]])))
+ numlimitlist[[i]] <-
+ extend.limits(as.numeric(numlimitlist[[i]]), length = slicelen)
+ }
+ ans <-
+ list(limits = limitlist,
+ used.at = used.at,
+ numlimitlist = numlimitlist,
+ slicelen = slicelen)
+ }
+ else if (relation == "free")
+ {
+ if (have.lim)
+ {
+ ## This is the only situation where limits can be a list
+ ## (doesn't make sense when relation="same", ignored when
+ ## relation="sliced"). Even if limits is not a list (but
+ ## is specified), it will be treated as a list, and
+ ## repeated as necessary (see further comments below).
+
+ if (!is.list(lim)) lim <- list(lim)
+
+ ## There's a subtle consideration here. It is possible
+ ## for some panels to have nothing in them (or only NA's).
+ ## Such panels usually have their prepanel functions
+ ## return NA. When 'limits' is specified as a list, this
+ ## will be interpreted as the limit specification for the
+ ## non-empty panels only (this is an arbitrary choice, but
+ ## it usually makes more sense, even though it's less
+ ## general than the other choice).
+
+ ## which ones are non-NA?
+ id <- which(sapply(limitlist, function(x) !all(is.na(x))))
+
+ ## replace these with the limits supplied, except if the
+ ## supplied limits are NULL, in which case retain limits
+ ## calculated by prepanel.
+
+ old.limitlist <- limitlist
+ limitlist[id] <- lim
+ which.null <- sapply(limitlist, is.null)
+ limitlist[which.null] <- old.limitlist[which.null]
+
+ ## lim overrides prepanel except NAs
+ for (i in seq_along(limitlist))
+ {
+ if (!is.character(limitlist[[i]]) &&
+ !is.character(old.limitlist[[i]]))
+ {
+ isna <- is.na(limitlist[[i]])
+ limitlist[[i]][isna] <- old.limitlist[[i]][isna]
+ }
+ }
+ }
+ for (i in seq_along(limitlist))
+ {
+ if (!all(is.na(limitlist[[i]])) && !is.character(limitlist[[i]]))
+ limitlist[[i]] <- ## preserves class
+ extend.limits(limitlist[[i]], axs = axs)
+ ## o.w., keep it as it is
+ }
+ slicelen <- numeric(length(limitlist))
+ for (i in seq_along(limitlist))
+ slicelen[i] <-
+ if (!is.character(limitlist[[i]]))
+ diff(range(as.numeric(limitlist[[i]])))
+ else if (!any(is.na(numlimitlist[[i]])))
+ diff(range(numlimitlist[[i]]))
+ else NA_real_
+ ans <-
+ list(limits = limitlist,
+ used.at = used.at,
+ numlimitlist = numlimitlist,
+ slicelen = slicelen)
+ }
+ ans
+}
+
+complete_names <- function(x, template, allow.invalid = FALSE)
+{
+ pid <- pmatch(names(x), names(template), duplicates.ok = TRUE)
+ if (allow.invalid) {
+ x <- x[!is.na(pid)]
+ pid <- pid[!is.na(pid)]
+ } else {
+ if (any(is.na(pid)))
+ warning("Invalid or ambiguous component names: ",
+ paste(names(x)[which(is.na(pid))], collapse = ", ") )
+ }
+ if (any(duplicated(pid))) stop("Multiple matches to component name")
+ names(x) <- names(template)[pid]
+ x
+}
+
+getFunctionOrName <- function(FUN)
+ ## Try lattice namespace first? Does that happen automatically?
+{
+ if (is.function(FUN)) FUN
+ else if (is.character(FUN)) get(FUN)
+ else eval(FUN)
+}
+
+trellis.skeleton <-
+ function(formula = NULL,
+ cond,
+ aspect = default.args$aspect, # argument in xyplot
+ as.table = default.args$as.table,
+ between = default.args$between,
+ key = NULL,
+ legend = NULL,
+ page = default.args$page,
+ main = default.args$main,
+ sub = default.args$sub,
+ par.strip.text = default.args$par.strip.text,
+ layout = default.args$layout,
+ skip = default.args$skip,
+ strip = default.args$strip.default, # argument in xyplot
+ strip.left = FALSE,
+ xlab.default = NULL,
+ ylab.default = NULL,
+ xlab = NULL, # argument in xyplot
+ ylab = NULL, # argument in xyplot
+ xlab.top = NULL,
+ ylab.right = NULL,
+
+ panel, # argument in xyplot
+
+ xscale.components = default.args$xscale.components,
+ yscale.components = default.args$yscale.components,
+ axis = default.args$axis,
+
+ subscripts = TRUE, # ignored, for reasons given above
+
+ index.cond = NULL,
+ perm.cond = NULL,
+ ...,
+ par.settings = NULL,
+ plot.args = NULL,
+ lattice.options = NULL)
+{
+ default.args <- lattice.getOption("default.args")
+ if (is.null(skip)) skip <- FALSE
+ foo <-
+ list(formula = formula,
+ as.table = as.table,
+ aspect.fill = (aspect == "fill"),
+ ## key = key,
+ legend = construct.legend(legend = legend, key = key),
+ panel = panel,
+ page = page,
+ layout = layout,
+ skip = skip,
+ strip = if (is.logical(strip) && strip) "strip.default"
+ else strip,
+ strip.left = if (is.logical(strip.left) && strip.left) strip.custom(horizontal = FALSE)
+ else strip.left,
+ xscale.components = xscale.components,
+ yscale.components = yscale.components,
+ axis = axis,
+ xlab = xlab,
+ ylab = ylab,
+ xlab.default = xlab.default,
+ ylab.default = ylab.default,
+ xlab.top = xlab.top,
+ ylab.right = ylab.right,
+ main = main,
+ sub = sub,
+ x.between = 0,
+ y.between = 0,
+ par.settings = par.settings,
+ plot.args = plot.args,
+ lattice.options = lattice.options,
+ par.strip.text = par.strip.text,
+ index.cond = index.cond,
+ perm.cond = perm.cond)
+
+ if (!is.null(between$x)) foo$x.between <- between$x
+ if (!is.null(between$y)) foo$y.between <- between$y
+
+ foo$condlevels <- lapply(cond, levels)
+
+ list(foo = foo, dots = list(...))
+}
+
+
+
+
+
+
+
+
+cond.orders <- function(foo, ...)
+ ## function to determine order of panels within a cond. variable
+ ## foo: trellis object-to-be
+
+ ## calculate actual values for index.cond and perm.cond.
+ ## index.cond can be a function, in which case it would be used to
+ ## determing order of levels within conditioning variables
+
+ ## Question: should these be determined at run-time? Wouldn't be
+ ## impossible, but has the disadvantage that looking at the
+ ## trellis object will be totally uninformative in the default
+ ## case (when both would be NULL). In a sense, this is fine, since
+ ## having index.cond be a function is similar to having a prepanel
+ ## function. After all, the results depend only on the panel
+ ## contents, and those cannot be changed via update.
+
+{
+
+ ## the following to be used for changing order of conditioning
+ ## variables and indexing their levels. The object foo already has
+ ## components index.cond and perm.cond as whatever was passed to
+ ## the original function call. If these are NULL, suitable
+ ## defaults need to be computed. If foo$index.cond is a function,
+ ## index.cond has to be computed appropriately.
+
+ index.cond <-
+ vector(mode = "list",
+ length = length(foo$condlevels))
+
+ for (i in seq_along(foo$condlevels))
+ index.cond[[i]] <- seq_along(foo$condlevels[[i]])
+ perm.cond <- seq_len(length(foo$condlevels))
+
+ if (!is.null(foo$perm.cond))
+ {
+ if (all(sort(foo$perm.cond) == perm.cond))
+ perm.cond <- foo$perm.cond
+ else stop("Invalid value of perm.cond")
+ }
+ if (!is.null(foo$index.cond))
+ {
+ if (is.list(foo$index.cond) && length(foo$index.cond) == length(index.cond))
+ {
+ for (i in seq_along(foo$condlevels))
+ index.cond[[i]] <- index.cond[[i]][foo$index.cond[[i]]]
+ }
+ else if (is.function(foo$index.cond))
+ {
+ FUN <- foo$index.cond
+ nplots <- length(foo$panel.args)
+ panel.order <- numeric(nplots)
+ for (count in seq_len(nplots))
+ {
+ if (is.list(foo$panel.args[[count]]))
+ {
+ pargs <- c(foo$panel.args.common, foo$panel.args[[count]], list(...))
+ prenames <- names(formals(FUN))
+ if (!("..." %in% prenames)) pargs <- pargs[intersect(names(pargs), prenames)]
+ panel.order[count] <- do.call("FUN", pargs)
+ }
+ else ## this happens for empty panels
+ {
+ is.na(panel.order) <- count # panel.order[count] <- NA
+ }
+ }
+ dim(panel.order) <- sapply(foo$condlevels, length)
+ for (i in seq_along(foo$condlevels))
+ index.cond[[i]] <-
+ order(apply(panel.order, i, mean, na.rm = TRUE))
+ }
+ else stop("Invalid value of index.cond")
+ }
+ list(index.cond = index.cond, perm.cond = perm.cond)
+}
+
+
+construct.scales <-
+ function(draw = TRUE, axs = "r", tck = 1, tick.number = 5,
+ at = FALSE, labels = FALSE, log = FALSE,
+ alternating = TRUE, relation = "same",
+ abbreviate = FALSE, minlength = 4,
+ limits = NULL, format = NULL,
+ equispaced.log = TRUE,
+
+ lty = FALSE, lwd = FALSE, cex = FALSE, rot = FALSE,
+ col = FALSE, col.line = col, alpha = FALSE, alpha.line = alpha,
+ font = FALSE, fontfamily = FALSE, fontface = FALSE, lineheight = FALSE,
+
+ ..., ## NOTE: ... is currently ignored
+ x = NULL, y = NULL)
+{
+ ## top-level values
+ x.scales <- y.scales <-
+ list(draw = draw, axs = axs, tck = tck, tick.number = tick.number,
+ at = at, labels = labels, log = log,
+ alternating = alternating, relation = relation,
+ abbreviate = abbreviate, minlength = minlength,
+ limits = limits, format = format, equispaced.log = equispaced.log,
+ lty = lty, lwd = lwd, cex = cex, rot = rot,
+ col = col, col.line = col.line, alpha = alpha, alpha.line = alpha.line,
+ font = font, fontfamily = fontfamily, fontface = fontface, lineheight = lineheight)
+ ## override by component-specific values
+ if (!is.null(x))
+ {
+ if (is.character(x)) x <- list(relation = x)
+ x <- complete_names(x, x.scales)
+ x.scales[names(x)] <- x
+ }
+ if (!is.null(y))
+ {
+ if (is.character(y)) y <- list(relation = y)
+ y <- complete_names(y, y.scales)
+ y.scales[names(y)] <- y
+ }
+ if (is.logical(x.scales$alternating))
+ x.scales$alternating <-
+ if (x.scales$alternating) c(1,2)
+ else 1
+ if (is.logical(y.scales$alternating))
+ y.scales$alternating <-
+ if (y.scales$alternating) c(1,2)
+ else 1
+ for (nm in c("tck", "cex", "rot")) {
+ x.scales[[nm]] <- rep(x.scales[[nm]], length.out = 2)
+ y.scales[[nm]] <- rep(y.scales[[nm]], length.out = 2)
+ }
+ if (x.scales$relation == "same" && (is.list(x.scales$at) || is.list(x.scales$labels)))
+ stop("the 'at' and 'labels' components of 'scales' may not be lists when 'relation = \"same\"'")
+ if (y.scales$relation == "same" && (is.list(y.scales$at) || is.list(y.scales$labels)))
+ stop("the 'at' and 'labels' components of 'scales' may not be lists when 'relation = \"same\"'")
+ list(x.scales = x.scales, y.scales = y.scales)
+}
+
+cupdate <- function(index, maxim)
+{
+
+ ## This unexported function is used to handle arbitrary number of
+ ## conditioning variables : every time it is called, it increments
+ ## the "current" level of the conditioning variables suitably,
+ ## i.e., it tries to increment the level of the 1st conditining
+ ## variable (the one which varies fastest along panel order) and
+ ## if it happens to be at its maximum (last) value, it sets it to
+ ## the first value AND increments the "current" level of the 2nd
+ ## (next) conditioning variable recursively.
+
+ if(length(index)!=length(maxim)||length(maxim)<=0)
+ stop("Inappropriate arguments")
+ index[1] <- index[1] + 1
+ if (index[1] > maxim[1] && length(maxim) > 1)
+ c(1, cupdate(index[-1], maxim[-1]))
+ else index
+}
+limits.and.aspect <-
+ function(prepanel.default,
+ prepanel = NULL,
+ have.xlim = FALSE, xlim = NULL,
+ have.ylim = FALSE, ylim = NULL,
+ x.relation, y.relation,
+ panel.args.common = list(),
+ panel.args = list(),
+ aspect,
+ banking = lattice.getOption("banking"),
+ npackets = length(panel.args),
+ x.axs = "r", y.axs = "r",
+ ...) ## extra arguments for prepanel (for qqmathline)
+{
+ prepanel.default.function <- getFunctionOrName(prepanel.default)
+ prepanel <- getFunctionOrName(prepanel)
+ if (npackets<1) stop("need at least one panel")
+ x.limits <- vector("list", npackets)
+ y.limits <- vector("list", npackets)
+ x.used.at <- vector("list", npackets)
+ y.used.at <- vector("list", npackets)
+ x.num.limit <- vector("list", npackets)
+ y.num.limit <- vector("list", npackets)
+ dxdy <- vector("list", npackets)
+
+ for (count in seq_len(npackets))
+ {
+ if (is.list(panel.args[[count]]))
+ {
+ pargs <- c(panel.args.common, panel.args[[count]], list(...))
+ tem <- do.call("prepanel.default.function", pargs)
+ if (is.function(prepanel)) ## results will 'overwrite' defaults
+ {
+ prenames <- names(formals(prepanel))
+ if (!("..." %in% prenames)) pargs <- pargs[intersect(names(pargs), prenames)]
+ pretem <- do.call("prepanel", pargs)
+ ## prepanel() over-rides defaults except NAs - e.g. ylim = c(0, NA)
+ if (!is.null(pretem$xlim) && !is.character(pretem$xlim))
+ if (any(isna <- is.na(pretem$xlim)))
+ pretem$xlim[isna] <- tem$xlim[isna]
+ if (!is.null(pretem$ylim) && !is.character(pretem$ylim))
+ if (any(isna <- is.na(pretem$ylim)))
+ pretem$ylim[isna] <- tem$ylim[isna]
+ tem <- updateList(tem, pretem)
+ ## tem[names(pretem)] <- pretem
+ }
+ x.limits[[count]] <- tem$xlim
+ y.limits[[count]] <- tem$ylim
+ x.used.at[[count]] <- if (is.null(tem$xat)) NA else tem$xat
+ y.used.at[[count]] <- if (is.null(tem$yat)) NA else tem$yat
+ x.num.limit[[count]] <- if (is.null(tem$xat)) NA else range(tem$xat)
+ y.num.limit[[count]] <- if (is.null(tem$yat)) NA else range(tem$yat)
+ dxdy[[count]] <- list(dx = tem$dx, dy = tem$dy)
+ }
+ else ## this happens for empty panels
+ {
+ x.limits[[count]] <- c(NA_real_, NA_real_)
+ y.limits[[count]] <- c(NA_real_, NA_real_)
+ x.used.at[[count]] <- NA_real_
+ y.used.at[[count]] <- NA_real_
+ x.num.limit[[count]] <- NA_real_
+ y.num.limit[[count]] <- NA_real_
+ dxdy[[count]] <- list(dx = NA_real_, dy = NA_real_)
+ }
+ }
+
+ ## Some explanation might be helpful here. The for loop above
+ ## creates a list of xlims/ylims. Each of these might be either
+ ## numeric (when x/y is numeric, shingle or POSIXt etc), or levels
+ ## of a factor (that's how prepanel.default.functions are set
+ ## up). However, at this point, all x.limits[[i]] must be of the
+ ## same type. Returned limits must be in accordance with this
+ ## type. The only exception is when relation = "free", in which
+ ## case they may be different. This could happen if [xy]lim or
+ ## limits is supplied as a list in the high level function.
+
+ x.limits <-
+ limitsFromLimitlist(have.lim = have.xlim,
+ lim = xlim,
+ relation = x.relation,
+ limitlist = x.limits,
+ used.at = x.used.at,
+ numlimitlist = x.num.limit,
+ axs = x.axs,
+ npackets = npackets)
+ y.limits <-
+ limitsFromLimitlist(have.lim = have.ylim,
+ lim = ylim,
+ relation = y.relation,
+ limitlist = y.limits,
+ used.at = y.used.at,
+ numlimitlist = y.num.limit,
+ axs = y.axs,
+ npackets = npackets)
+
+ if (is.character(aspect))
+ {
+ if (aspect == "xy")
+ {
+ aspect <-
+ median(sapply(dxdy, banking) *
+ y.limits$slicelen /
+ x.limits$slicelen,
+ na.rm = TRUE)
+### old aspect calculation
+## aspect <- median(unlist(lapply(dxdy, banking)),
+## na.rm = TRUE) * y.limits$slicelen /
+## x.limits$slicelen
+## if (y.relation == "free" || x.relation == "free")
+## warning("'aspect=xy' when 'relation=free' is not sensible")
+ }
+ else if (aspect == "iso")
+ {
+ aspect <-
+ median(y.limits$slicelen / x.limits$slicelen,
+ na.rm = TRUE)
+ if (y.relation == "free" || x.relation == "free")
+ warning("'aspect=\"iso\"' approximate since 'relation=\"free\"'")
+ }
+ else aspect <- 1
+ }
+ list(x.limits = x.limits$limits,
+ y.limits = y.limits$limits,
+ x.used.at = x.limits$used.at,
+ y.used.at = y.limits$used.at,
+ x.num.limit = x.limits$numlimitlist,
+ y.num.limit = y.limits$numlimitlist,
+ aspect.ratio = aspect,
+ prepanel.default = prepanel.default,
+ prepanel = prepanel)
+}
+
diff --git a/R/smoothHexbin.R b/R/smoothHexbin.R
new file mode 100644
index 0000000..890e1ed
--- /dev/null
+++ b/R/smoothHexbin.R
@@ -0,0 +1,46 @@
+setClass("smoothbin",
+ representation("hexbin", wts="numeric"))
+
+setGeneric("hsmooth", function(bin, wts) standardGeneric("hsmooth"))
+
+smooth.hexbin <- function(bin, wts = c(48, 4, 1))
+{
+ if(!is(bin,"hexbin"))
+ stop("first argument must be a hexbin object")
+ cell <- bin at cell - 1
+ n <- as.integer(length(cell))
+ cnt <- bin at count
+ xbins <- bin at xbins
+ bdim <- bin at dimen
+ row <- bdim[1]
+ col <- bdim[2]
+ ncol <- col + 4
+ nrow <- row + 4
+ nmax <- ncol * nrow
+ sm <- rep.int(0:0, nmax)
+ nr <- cell %/% col + 2
+ nc <- cell %% col + 3
+ pad <- rep.int(0:0, nmax - n)
+ cell <- c(nr * ncol + nc, pad)
+ cnt <- c(cnt, pad)
+ ans <- .Fortran("hsm",
+ cell = as.integer(cell),
+ cnt = as.integer(cnt),
+ n = n,
+ nmax = as.integer(nmax),
+ sm = as.integer(sm),
+ ncol = as.integer(ncol),
+ wts = as.integer(wts),
+ PACKAGE = "hexbin")[c("cell","cnt","n")]
+ n <- ans$n
+ length(ans$cell) <- length(ans$cnt) <- n
+ bin at xbins <- xbins + 4
+ bin at xbnds <- addBit(bin at xbnds, f = 2/xbins)
+ bin at ybnds <- addBit(bin at ybnds, f = 2/xbins)
+ bin at dimen <- c(nrow, ncol)
+ bin at cell <- ans$cell
+ bin at count <- ans$cnt
+ new("smoothbin", bin, wts=wts)
+}
+
+setMethod("hsmooth", "hexbin", smooth.hexbin)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..d87cb7a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
+hexbin
+======
+[![Build Status](https://travis-ci.org/edzer/hexbin.png?branch=master)](https://travis-ci.org/edzer/hexbin)
+
+An R Package with binning and plotting functions for hexagonal bins.
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..eddd7c7
--- /dev/null
+++ b/TODO
@@ -0,0 +1,36 @@
+--------------
+Aug 10, 2014
+o get rid of functions in lattice.R, which were copied from lattice
+
+--------------
+o The new 3D plots -- should rather make the new functions "internal"
+ and choosable with *arguments* from given functions !
+
+o hexbin *class* {as mentioned by man/hexbin.Rd } -- done
+
+o find the references (on paper) and read !
+ --> "References" in ./Biocore-notes
+
+ ftp://www.galaxy.gmu.edu/pub/faculty/dcarr/eda/bin2d/
+ ftp://www.galaxy.gmu.edu/pub/faculty/dcarr/software/bin2d.rev/
+
+
+o example(hmatplot) is still doing many pages instead of one
+
+
+------------
+March 5, 2005
+o Implement conversions between different hexagon coordinate systems
+
+o Smoothing on a hexagonal basis using tensor products
+ + smoothing histograms
+ + smoothing the intensity of a Poisson process
+
+o Family of hex apply functions
+
+o Hbin list class and constructors
+
+---
+
+o Use standard convertColor() function more and
+ and try to get rid of dependency on 'colorspace'
diff --git a/build/vignette.rds b/build/vignette.rds
new file mode 100644
index 0000000..44c1e0f
Binary files /dev/null and b/build/vignette.rds differ
diff --git a/data/NHANES.rda b/data/NHANES.rda
new file mode 100644
index 0000000..6540520
Binary files /dev/null and b/data/NHANES.rda differ
diff --git a/debian/README.test b/debian/README.test
deleted file mode 100644
index 55a9142..0000000
--- a/debian/README.test
+++ /dev/null
@@ -1,8 +0,0 @@
-Notes on how this package can be tested.
-────────────────────────────────────────
-
-To run the unit tests provided by the package you can do
-
- sh run-unit-test
-
-in this directory.
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644
index b3d3ab4..0000000
--- a/debian/changelog
+++ /dev/null
@@ -1,11 +0,0 @@
-r-cran-hexbin (1.27.1-2) UNRELEASED; urgency=medium
-
- * Added missing copyright statement
-
- -- Andreas Tille <tille at debian.org> Sun, 15 May 2016 12:05:02 +0200
-
-r-cran-hexbin (1.27.1-1) unstable; urgency=medium
-
- * Initial upload (Closes: #824360)
-
- -- Andreas Tille <tille at debian.org> Sun, 15 May 2016 01:01:21 +0200
diff --git a/debian/compat b/debian/compat
deleted file mode 100644
index ec63514..0000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-9
diff --git a/debian/control b/debian/control
deleted file mode 100644
index 9984338..0000000
--- a/debian/control
+++ /dev/null
@@ -1,24 +0,0 @@
-Source: r-cran-hexbin
-Maintainer: Debian Med Packaging Team <debian-med-packaging at lists.alioth.debian.org>
-Uploaders: Andreas Tille <tille at debian.org>
-Section: gnu-r
-Priority: optional
-Build-Depends: debhelper (>= 9),
- r-base-dev,
- r-cran-lattice,
- cdbs
-Standards-Version: 3.9.8
-Vcs-Browser: https://anonscm.debian.org/viewvc/debian-med/trunk/packages/R/r-cran-hexbin/
-Vcs-Svn: svn://anonscm.debian.org/debian-med/trunk/packages/R/r-cran-hexbin/
-Homepage: http://cran.r-project.org/web/packages/hexbin
-
-Package: r-cran-hexbin
-Architecture: any
-Depends: ${shlibs:Depends},
- ${misc:Depends},
- ${R:Depends},
- r-cran-lattice
-Description: GNU R hexagonal binning routines
- This GNU R package contains binning and plotting functions for hexagonal
- bins. Now uses and relies on grid graphics and formal (S4) classes and
- methods.
diff --git a/debian/copyright b/debian/copyright
deleted file mode 100644
index 4f0142e..0000000
--- a/debian/copyright
+++ /dev/null
@@ -1,36 +0,0 @@
-Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
-Upstream-Contact: Edzer Pebesma <edzer.pebesma at uni-muenster.de>
-Upstream-Name: hexbin
-Source: http://cran.r-project.org/web/packages/hexbin/
-
-Files: *
-Copyright: 2012-2014 Edzer Pebesma <edzer.pebesma at uni-muenster.de>
-License: GPL-2+
-
-Files: src/*.f
-Copyright: 1991-1994 Dan Carr
- 2004 Nicholas Lewin-Koh and Martin Maechler
-License: GPL-2+
-
-Files: R/lattice.R
-Copyright: 2001-2006 Deepayan Sarkar <Deepayan.Sarkar at R-project.org>
- 2001-2005 Saikat DebRoy <saikat at stat.wisc.edu>
-License: GPL-2+
-
-Files: debian/*
-Copyright: 2015 Andreas Tille <tille at debian.org>
-License: GPL-2+
-
-License: GPL-2+
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- .
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- .
- On Debian systems, the complete text of the GNU General Public
- License version 2 can be found in ‘/usr/share/common-licenses/GPL-2’.
diff --git a/debian/docs b/debian/docs
deleted file mode 100644
index 50f6656..0000000
--- a/debian/docs
+++ /dev/null
@@ -1 +0,0 @@
-debian/README.test
diff --git a/debian/examples b/debian/examples
deleted file mode 100644
index 18244c8..0000000
--- a/debian/examples
+++ /dev/null
@@ -1 +0,0 @@
-vignettes
diff --git a/debian/rules b/debian/rules
deleted file mode 100755
index 04a2c2a..0000000
--- a/debian/rules
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/make -f
-
-include /usr/share/R/debian/r-cran.mk
-
-install/$(package)::
- find debian/$(package)/ -type f -exec chmod 644 {} +
diff --git a/debian/source/format b/debian/source/format
deleted file mode 100644
index 163aaf8..0000000
--- a/debian/source/format
+++ /dev/null
@@ -1 +0,0 @@
-3.0 (quilt)
diff --git a/debian/tests/control b/debian/tests/control
deleted file mode 100644
index a0a0edc..0000000
--- a/debian/tests/control
+++ /dev/null
@@ -1,3 +0,0 @@
-Tests: run-unit-test
-Depends: @, r-cran-survival
-Restrictions: allow-stderr
diff --git a/debian/tests/run-unit-test b/debian/tests/run-unit-test
deleted file mode 100644
index abf88ff..0000000
--- a/debian/tests/run-unit-test
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/sh -e
-oname=hexbin
-pkg=r-cran-`echo $oname | tr [A-Z] [a-z]`
-
-if [ "$ADTTMP" = "" ] ; then
- ADTTMP=`mktemp -d /tmp/${pkg}-test.XXXXXX`
-fi
-cd $ADTTMP
-cp /usr/share/doc/$pkg/examples/vignettes/* $ADTTMP
-gunzip *.gz
-for rnw in `ls *.[rR]nw` ; do
-rfile=`echo $rnw | sed 's/\.[rR]nw/.R/'`
-R --no-save <<EOT
- Stangle("$rnw")
- source("$rfile", echo=TRUE)
-EOT
-done
-rm -rf *
diff --git a/debian/watch b/debian/watch
deleted file mode 100644
index b6c573a..0000000
--- a/debian/watch
+++ /dev/null
@@ -1,2 +0,0 @@
-version=3
-http://cran.r-project.org/src/contrib/hexbin_([\d.-]*)\.tar.gz
diff --git a/inst/doc/hexagon_binning.R b/inst/doc/hexagon_binning.R
new file mode 100644
index 0000000..7c08d1d
--- /dev/null
+++ b/inst/doc/hexagon_binning.R
@@ -0,0 +1,233 @@
+### R code from vignette source 'hexagon_binning.Rnw'
+
+###################################################
+### code chunk number 1: comphexsq
+###################################################
+library("hexbin")#,lib.loc="/home/nikko/R-devel/hex.devel/tst")
+x <- rnorm(1000)
+y <- rnorm(1000)
+##-- Hexagon Bins: --
+hbin <- hexbin(x,y, xbins = 25)
+grid.newpage()
+pushViewport(viewport(layout=grid.layout(1, 2)))
+pushViewport(viewport(layout.pos.col=1,layout.pos.row=1))
+plot(hbin, style="lattice", legend=0, xlab = "X", ylab = "Y", newpage=FALSE)
+popViewport()
+
+##-- Manual "square" binning: --
+## grid
+rx <- range(x); bx <- seq(rx[1],rx[2], length=29)
+ry <- range(y); by <- seq(ry[1],ry[2], length=29)
+## midpoints
+mx <- (bx[-1]+bx[-29])/2
+my <- (by[-1]+by[-29])/2
+gg <- as.matrix(expand.grid(mx,my))# dim = (28^2, 2)
+zz <- unname(table(cut(x, b = bx), cut(y, b = by)))# 28 x 28
+ind <- zz > 0
+if(FALSE) ## ASCII image:
+ symnum(unname(ind))
+sq.size <- zz[ind]^(1/3) / max(zz)
+## if we used base graphics:
+## symbols(gg[ind,], squares = sq.size, inches = FALSE, fg = 2, bg = 2)
+pushViewport(viewport(layout.pos.col=2, layout.pos.row=1))
+vp <- plot(hbin, style="lattice", legend=0,
+ xlab = "X", ylab = "Y", newpage=FALSE, type="n")
+pushHexport(vp$plot, clip="on")
+grid.rect(x= gg[ind,1], y=gg[ind,2], width = sq.size, height= sq.size,
+ default.units = "native", gp = gpar(col="black",fill="black"))
+popViewport()
+
+
+###################################################
+### code chunk number 2: nearNeighbor
+###################################################
+x <- -2:2
+sq <- expand.grid(list(x = x, y = c(-1,0,1)))
+fc.sq <- rbind(sq,sq+.5) # face centered squares
+fc.sq$y <- sqrt(3)*fc.sq$y # stretch y by the sqrt(3)
+nr <- length(fc.sq$x)/2
+
+
+###################################################
+### code chunk number 3: hexagon_binning.Rnw:138-170
+###################################################
+par(mfrow = c(3,1))
+par(mai = c(.1667,0.2680,0.1667,0.2680)) ##par(mai=.25*par("mai"))
+plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5)
+nr <- length(fc.sq$x)/2
+points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5)
+points(-.25,.15, col = 2, pch = 16, cex = .5)
+
+par(mai = c(.1667, 0.2680, 0.1667, 0.2680))##par(mai=.25*par("mai"))
+plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5)
+nr <- length(fc.sq$x)/2
+points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5)
+px <- c(-1,-2,-2,-1)+1
+py <- sqrt(3)*(c(0,0,-1,-1)+1)
+polygon(px, py, density = 0, col = 5)
+polygon(px+.5, py-sqrt(3)/2, density = 0)
+points(-.25, .15, col = 2, pch = 16, cex = .5)
+
+par(mai = c(.1667, 0.2680, 0.1667, 0.2680))##par(mai=.25*par("mai"))
+plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5)
+nr <- length(fc.sq$x)/2
+points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5)
+px <- c(-1,-2,-2,-1) + 1
+py <- sqrt(3)*(c(0,0,-1,-1) + 1)
+polygon(px, py, density = 0, col = 5)
+polygon(px+.5, py-sqrt(3)/2, density = 0)
+px <- c(-.5,-.5,0,.5, .5, 0)
+py <- c(-.5, .5,1,.5,-.5,-1) /sqrt(3)
+polygon(px, py, col = gray(.5), density = 0)
+polygon(px-.5, py+sqrt(3)/2, density = 0, col = 4)
+points(-.25, .15, col = 2, pch = 16, cex = .5)
+plot.new()
+arrows(-.25, .15, 0, 0, angle = 10, length = .05)
+
+
+###################################################
+### code chunk number 4: basic
+###################################################
+x <- rnorm(20000)
+y <- rnorm(20000)
+hbin <- hexbin(x,y, xbins = 40)
+plot(hbin)
+
+
+###################################################
+### code chunk number 5: showcol
+###################################################
+#nf <- layout(matrix(c(1,1,2,2,4,3,3,4), ncol=4, nrow=2, byrow=TRUE),
+# widths = rep(1,4), heights=rep(1,2))
+grid.newpage()
+mar <- unit(0.1 + c(5,4,4,2),"lines")
+mai <- as.numeric(convertUnit(mar, "inches"))
+vpin <- c(convertWidth (unit(1,"npc"),"inches"),
+ convertHeight(unit(1,"npc"),"inches"))
+shape <- optShape(height = vpin[2],width = vpin[1]/3,mar = mai)
+
+x <- rnorm(20000)
+y <- rnorm(20000)
+hbin <- hexbin(x,y, xbins = 40, shape = shape)
+grid.newpage()
+pushViewport(viewport(layout = grid.layout(1, 3)))
+pushViewport(viewport(layout.pos.col = 1,layout.pos.row = 1))
+plot(hbin, legend = 0, xlab = "X", ylab = "Y", newpage = FALSE)
+popViewport()
+pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1))
+plot(hbin, legend = 0, xlab = "X", ylab = "Y",
+ newpage = FALSE, colramp = terrain.colors)
+popViewport()
+pushViewport(viewport(layout.pos.col = 3,layout.pos.row = 1))
+plot(hbin, legend = 0, xlab = "X", ylab = "Y",
+ newpage = FALSE, colramp = BTY)
+popViewport()
+
+
+###################################################
+### code chunk number 6: showsmth
+###################################################
+#nf <- layout(matrix(c(1,1,2,2,4,3,3,4), ncol=4, nrow=2, byrow=TRUE),
+# widths = rep(1,4), heights=rep(1,2))
+x <- rnorm(10000)
+y <- rnorm(10000)
+grid.newpage()
+mar <- unit(0.1 + c(5,4,4,2),"lines")
+mai <- as.numeric(convertUnit(mar, "inches"))
+vpin <- c(convertWidth (unit(1,"npc"), "inches"),
+ convertHeight(unit(1,"npc"), "inches"))
+shape <- optShape(height = vpin[2],width = vpin[1]/3,mar = mai)
+hbin <- hexbin(x,y, xbins = 30,shape = shape)
+hsmbin1 <- hsmooth(hbin, c( 1, 0,0))
+hsmbin2 <- hsmooth(hbin, c(24,12,0))
+hsmbin2 at count <- as.integer(ceiling(hsmbin2 at count/sum(hsmbin2 at wts)))
+hsmbin3 <- hsmooth(hbin,c(48,24,12))
+hsmbin3 at count <- as.integer(ceiling(hsmbin3 at count/sum(hsmbin3 at wts)))
+pushViewport(viewport(layout = grid.layout(1, 3)))
+pushViewport(viewport(layout.pos.col = 1, layout.pos.row = 1))
+plot(hsmbin1, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY)
+popViewport()
+pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1))
+plot(hsmbin2, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY)
+popViewport()
+pushViewport(viewport(layout.pos.col = 3,layout.pos.row = 1))
+plot(hsmbin3, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY)
+popViewport()
+
+
+###################################################
+### code chunk number 7: hbox
+###################################################
+data(NHANES)
+#grid.newpage()
+mar <- unit(0.1 + c(5,4,4,2),"lines")
+mai <- as.numeric(convertUnit(mar, "inches"))
+#vpin <- c(convertWidth (unit(1,"npc"), "inches"),
+# convertHeight(unit(1,"npc"), "inches"))
+vpin <- c(unit(6,"inches"),unit(4, "inches"))
+shape <- optShape(height = vpin[2], width = vpin[1], mar = mai)
+hb <- hexbin(NHANES$Transferin, NHANES$Hemoglobin, shape = shape)
+hbhp <- hboxplot(erode(hb,cdfcut = .05),unzoom = 1.3)
+pushHexport(hbhp,clip = 'on')
+hexGraphPaper(hb,fill.edges = 3)
+popViewport()
+
+
+###################################################
+### code chunk number 8: hdiff
+###################################################
+#grid.newpage()
+shape <- optShape(height = vpin[2],width = vpin[1],mar = mai)
+xbnds <- range(NHANES$Transferin,na.rm = TRUE)
+ybnds <- range(NHANES$Hemoglobin,na.rm = TRUE)
+hbF <- hexbin(NHANES$Transferin[NHANES$Sex == "F"],
+ NHANES$Hemoglobin[NHANES$Sex == "F"],
+ xbnds = xbnds, ybnds = ybnds, shape = shape)
+hbM <- hexbin(NHANES$Transferin[NHANES$Sex == "M"],
+ NHANES$Hemoglobin[NHANES$Sex == "M"],
+ xbnds = xbnds, ybnds = ybnds, shape = shape)
+plot.new()
+hdiffplot(erode(hbF,cdfcut = .25),erode(hbM,cdfcut = .25),unzoom = 1.3)
+
+
+###################################################
+### code chunk number 9: marray1
+###################################################
+### Need to redo this part.
+library("marray")
+data(swirl, package = "marray") ## use swirl dataset
+
+hb1 <- hexbin(maA(swirl[,1]), maM(swirl[,1]), xbins = 40)
+grid.newpage()
+pushViewport(viewport(layout = grid.layout(1, 2)))
+
+pushViewport(viewport(layout.pos.col = 1,layout.pos.row = 1))
+nb <- plot(hb1, type = 'n', xlab = 'A', ylab = 'M',
+ main = "M vs A plot with points", legend = 0, newpage = FALSE)
+pushHexport(nb$plot.vp)
+grid.points(maA(swirl[,1]), maM(swirl[,1]),pch = 16,gp = gpar(cex = .4))
+popViewport()
+nb$hbin <- hb1
+hexVP.abline(nb$plot.vp,h = 0,col = gray(.6))
+hexMA.loess(nb)
+popViewport()
+
+pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1))
+hb <- plotMAhex(swirl[,1], newpage = FALSE,
+ main = "M vs A plot with hexagons", legend = 0)
+hexVP.abline(hb$plot.vp,h = 0,col = gray(.6))
+hexMA.loess(hb)
+popViewport()
+
+
+###################################################
+### code chunk number 10: addto
+###################################################
+hplt <- plot(hb1,style = 'centroid',border = gray(.65))
+pushHexport(hplt$plot.vp)
+ll.fit <- loess(hb1 at ycm ~ hb1 at xcm, weights = hb1 at count, span = .4)
+pseq <- seq(hb1 at xbnds[1]+1, hb1 at xbnds[2]-1, length = 100)
+grid.lines(pseq, predict(ll.fit,pseq),
+ gp = gpar(col = 2), default.units = "native")
+
+
diff --git a/inst/doc/hexagon_binning.Rnw b/inst/doc/hexagon_binning.Rnw
new file mode 100644
index 0000000..898c739
--- /dev/null
+++ b/inst/doc/hexagon_binning.Rnw
@@ -0,0 +1,498 @@
+%% Emacs: use Rnw-mode if available, else noweb
+%% NOTE -- ONLY EDIT THE .Rnw FILE !
+
+%\VignetteIndexEntry{Hexagon Binning}
+%\VignetteDepends{hexbin, grid, marray}
+%\VignetteKeywords{Over plotting, Large data set, Visualization}
+%\VignettePackage{hexbin}
+
+\documentclass[]{article}
+
+\usepackage[authoryear,round]{natbib}
+\usepackage{amsmath}
+\usepackage{hyperref}
+
+
+\author{Nicholas Lewin-Koh\footnote{with minor assistance by Martin M\"achler}}
+
+\begin{document}
+
+\title{Hexagon Binning: an Overview}
+\maketitle{}
+
+\section{Overview}
+Hexagon binning is a form of bivariate histogram useful for visualizing
+the structure in datasets with large $n$. The underlying concept of
+hexagon binning is extremely simple;
+\begin{enumerate}
+\item the $xy$ plane over the set (range($x$), range($y$)) is tessellated
+by a regular grid of hexagons.
+
+\item the number of points falling in each hexagon are counted and
+stored in a data structure
+
+\item the hexagons with count $ > 0$ are plotted using a color ramp or
+varying the radius of the hexagon in proportion to the counts.
+\end{enumerate}
+
+The underlying algorithm is extremely fast and effective for displaying
+the structure of datasets with $n \ge 10^6$.
+If the size of the grid and the cuts in the color ramp are chosen in a
+clever fashion than the structure inherent in the data should emerge
+in the binned plots. The same caveats apply to hexagon binning as
+apply to histograms and care should be exercised in choosing the
+binning parameters.
+
+The hexbin package is a set of function for creating, manipulating and
+plotting hexagon bins. The package extends the basic hexagon binning
+ideas with several functions for doing bivariate smoothing, finding an
+approximate bivariate median, and looking at the difference between
+two sets of bins on the same scale. The basic functions can be
+incorporated into many types of plots. This package is based on the
+original package for S-PLUS by Dan Carr at George Mason University and
+is mostly the fruit of his graphical genius and intuition.
+
+\section{Theory and Algorithm}
+Why hexagons? There are many reasons for using hexagons, at least over
+squares. Hexagons have symmetry of nearest neighbors which is lacking
+in square bins. Hexagons are the maximum number of sides a polygon can
+have for a regular tesselation of the plane, so in terms of packing a
+hexagon is 13\% more efficient for covering the plane than
+squares. This property translates into better sampling efficiency at
+least for elliptical shapes. Lastly hexagons are visually less biased
+for displaying densities than other regular tesselations. For instance
+with squares our eyes are drawn to the horizontal and vertical lines
+of the grid. The following figure adapted from \cite[]{carretal}shows
+this effectively.
+
+\begin{figure}[H]
+ \centering
+<<comphexsq, fig=TRUE, width=7, height=4, echo=FALSE>>=
+library("hexbin")#,lib.loc="/home/nikko/R-devel/hex.devel/tst")
+x <- rnorm(1000)
+y <- rnorm(1000)
+##-- Hexagon Bins: --
+hbin <- hexbin(x,y, xbins = 25)
+grid.newpage()
+pushViewport(viewport(layout=grid.layout(1, 2)))
+pushViewport(viewport(layout.pos.col=1,layout.pos.row=1))
+plot(hbin, style="lattice", legend=0, xlab = "X", ylab = "Y", newpage=FALSE)
+popViewport()
+
+##-- Manual "square" binning: --
+## grid
+rx <- range(x); bx <- seq(rx[1],rx[2], length=29)
+ry <- range(y); by <- seq(ry[1],ry[2], length=29)
+## midpoints
+mx <- (bx[-1]+bx[-29])/2
+my <- (by[-1]+by[-29])/2
+gg <- as.matrix(expand.grid(mx,my))# dim = (28^2, 2)
+zz <- unname(table(cut(x, b = bx), cut(y, b = by)))# 28 x 28
+ind <- zz > 0
+if(FALSE) ## ASCII image:
+ symnum(unname(ind))
+sq.size <- zz[ind]^(1/3) / max(zz)
+## if we used base graphics:
+## symbols(gg[ind,], squares = sq.size, inches = FALSE, fg = 2, bg = 2)
+pushViewport(viewport(layout.pos.col=2, layout.pos.row=1))
+vp <- plot(hbin, style="lattice", legend=0,
+ xlab = "X", ylab = "Y", newpage=FALSE, type="n")
+pushHexport(vp$plot, clip="on")
+grid.rect(x= gg[ind,1], y=gg[ind,2], width = sq.size, height= sq.size,
+ default.units = "native", gp = gpar(col="black",fill="black"))
+popViewport()
+@
+ \caption[bivariate: squares and hexagons]{A bivariate point set binned
+ into squares and hexagons. Bins are
+ scaled approximately equal, and the size of the glyph is proportional
+ to the count in that bin.}
+ \label{fig:compHexSq}
+\end{figure}
+
+
+We can see in Figure~\ref{fig:compHexSq} that when the data are plotted
+as squares centered on a regular lattice our eye is drawn to the regular lines
+which are parallel to the underlying grid. Hexagons tend to break up
+the lines.
+
+How does does the hexagon binning algorithm work?
+
+\begin{enumerate}
+\item Squash $Y$ by $\sqrt{3}$
+\item Create a dual lattice
+\item Bin each point into pair of near neighbor rectangles
+\item Pick closest of the rectangle centers (adjusting for $\sqrt{3}$)
+\end{enumerate}
+
+
+<< nearNeighbor, echo = false, results = hide >>=
+x <- -2:2
+sq <- expand.grid(list(x = x, y = c(-1,0,1)))
+fc.sq <- rbind(sq,sq+.5) # face centered squares
+fc.sq$y <- sqrt(3)*fc.sq$y # stretch y by the sqrt(3)
+nr <- length(fc.sq$x)/2
+@
+
+\begin{figure}[H]
+ \centering
+<< fig = TRUE,width = 4,height = 8,echo = FALSE >>=
+par(mfrow = c(3,1))
+par(mai = c(.1667,0.2680,0.1667,0.2680)) ##par(mai=.25*par("mai"))
+plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5)
+nr <- length(fc.sq$x)/2
+points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5)
+points(-.25,.15, col = 2, pch = 16, cex = .5)
+
+par(mai = c(.1667, 0.2680, 0.1667, 0.2680))##par(mai=.25*par("mai"))
+plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5)
+nr <- length(fc.sq$x)/2
+points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5)
+px <- c(-1,-2,-2,-1)+1
+py <- sqrt(3)*(c(0,0,-1,-1)+1)
+polygon(px, py, density = 0, col = 5)
+polygon(px+.5, py-sqrt(3)/2, density = 0)
+points(-.25, .15, col = 2, pch = 16, cex = .5)
+
+par(mai = c(.1667, 0.2680, 0.1667, 0.2680))##par(mai=.25*par("mai"))
+plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5)
+nr <- length(fc.sq$x)/2
+points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5)
+px <- c(-1,-2,-2,-1) + 1
+py <- sqrt(3)*(c(0,0,-1,-1) + 1)
+polygon(px, py, density = 0, col = 5)
+polygon(px+.5, py-sqrt(3)/2, density = 0)
+px <- c(-.5,-.5,0,.5, .5, 0)
+py <- c(-.5, .5,1,.5,-.5,-1) /sqrt(3)
+polygon(px, py, col = gray(.5), density = 0)
+polygon(px-.5, py+sqrt(3)/2, density = 0, col = 4)
+points(-.25, .15, col = 2, pch = 16, cex = .5)
+plot.new()
+arrows(-.25, .15, 0, 0, angle = 10, length = .05)
+@
+\caption[Near Neighbor Rectangles]{}
+\label{fig:binalg}
+\end{figure}
+
+Figure~\ref{fig:binalg} shows graphically how the algorithm works. In
+the first panel we see the the dual lattice laid out in black and blue
+points. The red point is an arbitrary point to be binned. The second
+panel shows the near neigbor rectangles for each lattice around the
+point to be binned, the intersection of the rectangles contains the
+point. The last panel shows the simple test for locating the point in
+the hexagon, the closest of the two corners which are not
+intersections is the center of the hexagon to which the point should
+be allocated. The binning can be calculated in one pass through the
+data, and is clearly $O(n)$ with a small constant. Storage is vastly
+reduced compared to the original data.
+
+\section{Basic Hexagon Binning Functions}
+Using the basic hexagon binning functions are not much more involved
+than using the basic plotting functions. The following little example
+shows the basic features of the basic plot and binning functions.
+We start by loading the package and generating a toy example data set.
+
+<< basic, fig = TRUE, results = hide >>=
+x <- rnorm(20000)
+y <- rnorm(20000)
+hbin <- hexbin(x,y, xbins = 40)
+plot(hbin)
+@
+There are two things to note here. The first is that the function
+\texttt{gplot.hexbin} is defined as a \texttt{plot} method for the S4 class
+\texttt{hexbin}. The second is that the default color scheme for the
+hexplot is a gray scale. However, there is an argument to plot,
+\texttt{colramp}, that allows the use of any function that excepts an
+argument \texttt{n} and returns $n$ colors. Several functions are supplied
+that provide alternative color-ramps to R's built in color ramp functions,
+see \texttt{help(ColorRamps)}.
+
+<< showcol, fig = TRUE, width = 7, height = 4, echo = FALSE >>=
+#nf <- layout(matrix(c(1,1,2,2,4,3,3,4), ncol=4, nrow=2, byrow=TRUE),
+# widths = rep(1,4), heights=rep(1,2))
+grid.newpage()
+mar <- unit(0.1 + c(5,4,4,2),"lines")
+mai <- as.numeric(convertUnit(mar, "inches"))
+vpin <- c(convertWidth (unit(1,"npc"),"inches"),
+ convertHeight(unit(1,"npc"),"inches"))
+shape <- optShape(height = vpin[2],width = vpin[1]/3,mar = mai)
+
+x <- rnorm(20000)
+y <- rnorm(20000)
+hbin <- hexbin(x,y, xbins = 40, shape = shape)
+grid.newpage()
+pushViewport(viewport(layout = grid.layout(1, 3)))
+pushViewport(viewport(layout.pos.col = 1,layout.pos.row = 1))
+plot(hbin, legend = 0, xlab = "X", ylab = "Y", newpage = FALSE)
+popViewport()
+pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1))
+plot(hbin, legend = 0, xlab = "X", ylab = "Y",
+ newpage = FALSE, colramp = terrain.colors)
+popViewport()
+pushViewport(viewport(layout.pos.col = 3,layout.pos.row = 1))
+plot(hbin, legend = 0, xlab = "X", ylab = "Y",
+ newpage = FALSE, colramp = BTY)
+popViewport()
+@
+
+The figure shows three examples of using hexagons in a plot for large $n$ with
+different color schemes. Upper left: the default gray scale, upper right: the
+R base \texttt{terrain.colors()}, and lower middle: \texttt{BTY()}, a
+blue to yellow color ramp supplied with hexbin on a perceptually linear
+scale.
+
+The hexbin package supplies a plotting method for the hexbin data
+structure. The plotting method \texttt{gplot.hexbin} accepts all the
+parameters for the hexagon function and supplies a legend as well, for
+easy interpretation of the plot. Figure~2 shows a hex binned plot with
+a legend. A function \texttt{grid.hexlegend} is supplied for creating user
+specified hexagon legends.
+
+\section{Extended Hexagon Functions}
+So far we have looked at the basic hexagon plot. The hexbin package
+supplies several extensions to the basic hexbin, and the associated
+hexplot. The extensions discussed in this section will be smoothing
+hexbin objects using the hsmooth function, approximating a bivariate
+median with hexagons and a version of a bivariate boxplot, and using
+eroded hexbin objects to look at the overlap of two bivariate populations.
+
+\subsection{Smoothing with \texttt{hsmooth}}
+At this point the hexbin package only provides a single option for
+smoothing using a discrete kernel. Several improvements are in
+development including an apply function over neighborhoods and spline
+functions using a hexagonal basis or tensor products. The apply
+function should facilitate constructing more sophisticated kernel
+smoothers. The hexagon splines will provide an alternative to
+smoothing on a square grid and allow interpolation of hexagons to
+finer grids.
+
+The current implementation uses the center cell, immediate
+neighbors and second neighbors to smooth the counts. The counts for
+each resulting cell is a linear combination of the counts in the
+defined neighborhood, including the center cell and weights. The
+counts are blurred over the the domain, and the domain increases
+because of shifting. Generally the dimension of the occupied cells of
+the lattice increases by one, sometimes two.
+
+Some examples of using the hsmooth function are given below. Notice in
+the plots that the first plot is with no smoothing, weights are
+\texttt{c(1,0,0)} meaning that only the center cell is used with
+identity weights. The second plot shows a first order kernel using
+weights \texttt{c(24,12,0)}, while the third plot uses weights for
+first and second order neighbors specified as \texttt{c(48,24,12)}.
+The code segment generating these plots rescales the smoothed counts
+so that they are on the original scale.
+
+<< showsmth, fig = TRUE, width = 8, height = 4, echo = FALSE >>=
+#nf <- layout(matrix(c(1,1,2,2,4,3,3,4), ncol=4, nrow=2, byrow=TRUE),
+# widths = rep(1,4), heights=rep(1,2))
+x <- rnorm(10000)
+y <- rnorm(10000)
+grid.newpage()
+mar <- unit(0.1 + c(5,4,4,2),"lines")
+mai <- as.numeric(convertUnit(mar, "inches"))
+vpin <- c(convertWidth (unit(1,"npc"), "inches"),
+ convertHeight(unit(1,"npc"), "inches"))
+shape <- optShape(height = vpin[2],width = vpin[1]/3,mar = mai)
+hbin <- hexbin(x,y, xbins = 30,shape = shape)
+hsmbin1 <- hsmooth(hbin, c( 1, 0,0))
+hsmbin2 <- hsmooth(hbin, c(24,12,0))
+hsmbin2 at count <- as.integer(ceiling(hsmbin2 at count/sum(hsmbin2 at wts)))
+hsmbin3 <- hsmooth(hbin,c(48,24,12))
+hsmbin3 at count <- as.integer(ceiling(hsmbin3 at count/sum(hsmbin3 at wts)))
+pushViewport(viewport(layout = grid.layout(1, 3)))
+pushViewport(viewport(layout.pos.col = 1, layout.pos.row = 1))
+plot(hsmbin1, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY)
+popViewport()
+pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1))
+plot(hsmbin2, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY)
+popViewport()
+pushViewport(viewport(layout.pos.col = 3,layout.pos.row = 1))
+plot(hsmbin3, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY)
+popViewport()
+@
+\subsection{Bin Erosion and the \texttt{hboxplot}}
+The next tool to introduce, gray level erosion, extends the idea of
+the boxplot. The idea is to extract cells in a way that the most
+exposed cells are removed first, ie cells with fewer neighbors, but
+cells with lower counts are removed preferentially to cells with
+higher counts. The algorithm works as follows:
+Mark the high count cells containing a given fraction, cdfcut, of
+the total counts. Mark all the cells if cdfcut is zero.
+The algorithm then performs gray-level erosion on the
+marked cells. Each erosion cycle removes counts from cells. The
+counts removed from each cell are a multiple of the cell's exposed-face
+count. The algorithm chooses the multiple so at least one cell will be
+empty or have a count deficit on each erosion cycle. The erode vector
+contains an erosion number for each cell. The value of erode is
+
+\begin{center}
+ $6\times$(The erosion cycle at cell removal) $ - $
+ (The cell deficit at removal)
+\end{center}
+
+The cell with the highest erosion number is a candidate bivariate
+median. A few ties in the erosion order are common.
+
+The notion of an ordering to the median is nice because it allows us
+to create a version of a bivariate box plot built on hexagons. The
+following example comes from a portion of the ''National Health and Nutrition
+Examination Survey'' included in \texttt{hexbin} as the sample data
+set NHANES. The data consist of 9575 persons and mesures various
+clinical factors. Here in Figure~\ref{hbox} we show the levels of
+transferin, a measure of iron binding against hemoglobin for all
+
+\begin{figure}[H]
+ \centering
+
+<< hbox, fig = TRUE, width = 6, height = 4, echo = FALSE >>=
+data(NHANES)
+#grid.newpage()
+mar <- unit(0.1 + c(5,4,4,2),"lines")
+mai <- as.numeric(convertUnit(mar, "inches"))
+#vpin <- c(convertWidth (unit(1,"npc"), "inches"),
+# convertHeight(unit(1,"npc"), "inches"))
+vpin <- c(unit(6,"inches"),unit(4, "inches"))
+shape <- optShape(height = vpin[2], width = vpin[1], mar = mai)
+hb <- hexbin(NHANES$Transferin, NHANES$Hemoglobin, shape = shape)
+hbhp <- hboxplot(erode(hb,cdfcut = .05),unzoom = 1.3)
+pushHexport(hbhp,clip = 'on')
+hexGraphPaper(hb,fill.edges = 3)
+popViewport()
+@
+\caption{Hexagon "boxplots" showing the top 95 percent of the data for
+ males and females. The red hexagons are an estimate of the bivariate median.}
+\label{hbox}
+\end{figure}
+
+Note that we have added ``hexagon graph paper'' to the plot. This can
+be done for any hexbin plot, using the command
+\texttt{hexGraphPaper()} where the main argument is the hexbin object.
+
+\subsection{Comparing Distributions and the \texttt{hdiffplot}}
+With univariate data, if there are multiple groups, one often uses a
+density estimate to overlay densities, and compare two or more
+distributions. The hdiffplot is the bivariate analog. The idea behind
+the hdiff plot is to plot one or more bin objects representing
+multiple groups to compare the distributions. The following example
+uses the National Health data supplied in the hexbin package,
+(\texttt{NHANES}). Below we show a comparison of males and females,
+the bivariate relationship is transferin, which is a derived measure
+of the ability of blood to bind oxygen, vs the level of hemoglobin.
+Note that in the call to \texttt{hdiffplot} we erode the bins to
+calculate the bivariate medians, and only display the upper 75\% of
+the data.
+\begin{figure}[H]
+ \centering
+<< hdiff, fig = TRUE, width = 6, height = 4, echo = TRUE >>=
+#grid.newpage()
+shape <- optShape(height = vpin[2],width = vpin[1],mar = mai)
+xbnds <- range(NHANES$Transferin,na.rm = TRUE)
+ybnds <- range(NHANES$Hemoglobin,na.rm = TRUE)
+hbF <- hexbin(NHANES$Transferin[NHANES$Sex == "F"],
+ NHANES$Hemoglobin[NHANES$Sex == "F"],
+ xbnds = xbnds, ybnds = ybnds, shape = shape)
+hbM <- hexbin(NHANES$Transferin[NHANES$Sex == "M"],
+ NHANES$Hemoglobin[NHANES$Sex == "M"],
+ xbnds = xbnds, ybnds = ybnds, shape = shape)
+plot.new()
+hdiffplot(erode(hbF,cdfcut = .25),erode(hbM,cdfcut = .25),unzoom = 1.3)
+@
+\caption{A difference plot of transferin vs hemoglobin for males and females.}
+\label{hdiffplot}
+\end{figure}
+
+
+
+\subsection{Plotting a Third Concomitant Variable}
+In many cases, such as with spatial data, one may want to plot the
+levels of a third variable in each hexagon. The grid.hexagons function
+has a pair of arguments, \texttt{use.count} and \texttt{cell.at}. If
+\texttt{use.count = FALSE} and \texttt{cell.at} is a numeric vector of
+the same length as \texttt{hexbin at count} then the attribute vector
+will be used instead of the counts. \texttt{hexTapply} will
+summarize values for each hexagon according to the supplied function
+and return the table in the right order to use as an attribute
+vector. Another alternative is to set the \texttt{cAtt} slot of the
+hexbin object and grid.hexagons will automatically plot the attribute
+if \texttt{use.count = FALSE} and \texttt{cell.at = NULL}.
+
+Here is an example using spatial data. Often cartographers use
+graduated symbols to display varying numerical quantities across a region.
+
+
+
+\section{Example: cDNA Chip Normalization}
+This example is taken from the marray package, which
+supplies methods and classes for the normalization and diagnostic
+plots of cDNA microarrays. In this example the goal is not to make any
+comments about the normalization methodology, but rather to show how
+the diagnostic plots can be enhanced using hexagon binning due to the
+large number of points ($n = 8,448$ cDNA probes per chip).
+
+We look at the diagnostic plot $M$ vs $A$, where $M$ is the
+log--ratio, $M = \log <- 2 \frac{R}{G}$ and $A$ is the overall intensity,
+$A = \log <- 2\sqrt{RG}$. Figure~3 shows the plot using points and on the
+right hexagons. The hexagon binned plot shows that most of the pairs
+are well below zero, and that the overall shape is more like a comet
+with most of the mass at the bottom of the curve, rather than a thick
+bar of points curving below the line.
+
+<< marray1, fig = TRUE, results = hide >>=
+### Need to redo this part.
+library("marray")
+data(swirl, package = "marray") ## use swirl dataset
+
+hb1 <- hexbin(maA(swirl[,1]), maM(swirl[,1]), xbins = 40)
+grid.newpage()
+pushViewport(viewport(layout = grid.layout(1, 2)))
+
+pushViewport(viewport(layout.pos.col = 1,layout.pos.row = 1))
+nb <- plot(hb1, type = 'n', xlab = 'A', ylab = 'M',
+ main = "M vs A plot with points", legend = 0, newpage = FALSE)
+pushHexport(nb$plot.vp)
+grid.points(maA(swirl[,1]), maM(swirl[,1]),pch = 16,gp = gpar(cex = .4))
+popViewport()
+nb$hbin <- hb1
+hexVP.abline(nb$plot.vp,h = 0,col = gray(.6))
+hexMA.loess(nb)
+popViewport()
+
+pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1))
+hb <- plotMAhex(swirl[,1], newpage = FALSE,
+ main = "M vs A plot with hexagons", legend = 0)
+hexVP.abline(hb$plot.vp,h = 0,col = gray(.6))
+hexMA.loess(hb)
+popViewport()
+@
+
+
+
+\section{Manipulating Hexbins}
+The underlying functions for hexbin have been rewritten and now depend
+on the grid graphics system. The support unit for all hexagon plots is
+the hexViewport. The function \texttt{hexViewport()} takes a hexbin
+object as input and creates a viewport scaled to the current device or
+viewport so that the aspect ratio is scaled appropriately for the
+hexagons. Unlike in the base graphic functions where the aspect ratio
+is maintained by shifting the range of the axes, here the extra space
+is shifted into the margins. Currently hexViewport returns a
+hexViewport object that has information on the margins and
+its own pushViewport method. In the next example we will 1st show how
+to manipulate an existing plot using grid commands and second show how to
+create a custom plotting function using \texttt{hexViewport} and grid.
+
+\subsection{Adding to an existing plot}
+Adding to an existing plot requires the use of grid
+functions. For instance, in the following code,
+<< addto,fig = TRUE,echo = TRUE >>=
+hplt <- plot(hb1,style = 'centroid',border = gray(.65))
+pushHexport(hplt$plot.vp)
+ll.fit <- loess(hb1 at ycm ~ hb1 at xcm, weights = hb1 at count, span = .4)
+pseq <- seq(hb1 at xbnds[1]+1, hb1 at xbnds[2]-1, length = 100)
+grid.lines(pseq, predict(ll.fit,pseq),
+ gp = gpar(col = 2), default.units = "native")
+@
+we have to use \texttt{grid.lines()}, as opposed to \texttt{lines()}.
+
+
+\end{document}
diff --git a/inst/doc/hexagon_binning.pdf b/inst/doc/hexagon_binning.pdf
new file mode 100644
index 0000000..73af27f
Binary files /dev/null and b/inst/doc/hexagon_binning.pdf differ
diff --git a/man/NHANES.Rd b/man/NHANES.Rd
new file mode 100644
index 0000000..f064fa4
--- /dev/null
+++ b/man/NHANES.Rd
@@ -0,0 +1,52 @@
+\name{NHANES}
+\alias{NHANES}
+\docType{data}
+\title{NHANES Data : National Health and Nutrition Examination Survey}
+\usage{data(NHANES)}
+\description{
+ This is a somewhat large interesting dataset, a data frame of 15
+ variables (columns) on 9575 persons (rows).
+}
+\format{
+ This data frame contains the following columns:
+ \describe{
+ \item{Cancer.Incidence}{binary factor with levels \code{No} and \code{Yes}.}
+ \item{Cancer.Death}{binary factor with levels \code{No} and \code{Yes}.}
+ \item{Age}{numeric vector giving age of the person in years.}
+ \item{Smoke}{a factor with levels \code{Current}, \code{Past},
+ \code{Nonsmoker}, and \code{Unknown}.}
+ \item{Ed}{numeric vector of \eqn{\{0,1\}} codes giving the education level.}
+ \item{Race}{numeric vector of \eqn{\{0,1\}} codes giving the
+ person's race.%% FIXME : 0 = ? 1 = ?
+ }
+ \item{Weight}{numeric vector giving the weight in kilograms}
+ \item{BMI}{numeric vector giving Body Mass Index, i.e.,
+ \code{Weight/Height^2} where Height is in meters, and missings
+ (61\% !) are coded as \code{0} originally.}%% rather FIXME?
+ \item{Diet.Iron}{numeric giving Dietary iron.}
+ \item{Albumin}{numeric giving albumin level in g/l.}
+ \item{Serum.Iron}{numeric giving Serum iron in \eqn{\mu}{u}g/l.}
+ \item{TIBC}{numeric giving Total Iron Binding Capacity in \eqn{\mu}{u}g/l.}
+ \item{Transferin}{numeric giving Transferin Saturation which is just
+ \code{100*serum.iron/TIBC}.}
+ \item{Hemoglobin}{numeric giving Hemoglobin level.}
+ \item{Sex}{a factor with levels \code{F} (female) and \code{M} (male).}
+ }
+}
+\examples{
+data(NHANES)
+summary(NHANES)
+## Missing Data overview :
+nNA <- sapply(NHANES, function(x)sum(is.na(x)))
+cbind(nNA[nNA > 0])
+# Which are just these 6 :
+\dontrun{
+Diet.Iron 141
+Albumin 252
+Serum.Iron 1008
+TIBC 853
+Transferin 1019
+Hemoglobin 759
+}%dont
+}
+\keyword{datasets}
diff --git a/man/colramp.Rd b/man/colramp.Rd
new file mode 100644
index 0000000..3ca5627
--- /dev/null
+++ b/man/colramp.Rd
@@ -0,0 +1,60 @@
+\name{ColorRamps}
+\title{Color Ramps on Perceptually Linear Scales}
+\alias{ColorRamps}
+\alias{LinGray}
+\alias{BTC}
+\alias{BTY}
+\alias{LinOCS}
+\alias{heat.ob}
+\alias{magent}
+\alias{plinrain}
+\description{
+ Functions for returning colors on perceptually linear scales,
+ where steps correspond to \sQuote{just detectable differences}.
+}
+\usage{
+LinGray (n, beg=1, end=92)
+BTC (n, beg=1, end=256)
+LinOCS (n, beg=1, end=256)
+heat.ob (n, beg=1, end=256)
+magent (n, beg=1, end=256)
+plinrain(n, beg=1, end=256)
+}
+\arguments{
+ \item{n}{number of colors to return from the ramp}
+ \item{beg}{begining of ramp, integer from 1-255}
+ \item{end}{end of ramp, integer from 1-255}
+}
+\value{
+ returns an array of colors
+}
+\details{
+ Several precalulated color ramps, that are on a perceptually linear
+ color scale. A perceptually linear color scale is a scale where each
+ jump corresponds to a \dQuote{just detectable difference} in color and the
+ scale is percieved as linear by the human eye (emprically determined).
+
+ When using the ramps, if \code{beg} is less than \code{end} the ramp
+ will be reversed.
+}
+\references{
+ Haim Levkowitz (1997)
+ \emph{Color Theory and Modeling for Computer Graphics,
+ Visualization, and Multimedia Applications}.
+ Kluwer Academic Publishers, Boston/London/Dordrecht.
+ \url{http://www.cs.uml.edu/~haim/ColorCenter/}
+}
+\seealso{
+ \code{\link[grDevices:palettes]{rainbow}},
+ \code{\link[grDevices:palettes]{terrain.colors}},
+ \code{\link[grDevices]{rgb}},
+ \code{\link[grDevices]{hsv}}
+}
+\examples{
+h <- hexbin(rnorm(10000),rnorm(10000))
+plot(h, colramp= BTY)
+## looks better if you shave the tails:
+plot(h, colramp= function(n){LinOCS(n,beg=15,end=225)})
+}
+\author{Nicholas Lewin-Koh}
+\keyword{color}
diff --git a/man/erode.hexbin.Rd b/man/erode.hexbin.Rd
new file mode 100644
index 0000000..79d2c90
--- /dev/null
+++ b/man/erode.hexbin.Rd
@@ -0,0 +1,86 @@
+\name{erode.hexbin}
+\alias{erode}
+\alias{erode.hexbin}
+\alias{erode,hexbin-method}
+\alias{erodebin-class}
+
+\title{Erosion of a Hexagon Count Image}
+\description{
+ This erosion algorithm removes counts from hexagon cells at a rate
+ proportional to the cells' exposed surface area. When a cell becomes
+ empty, algorithm removes the emptied cell and notes the removal
+ order. Cell removal increases the exposure of any neighboring cells.
+ The last cell removed is a type of bivariate median.
+}
+
+\usage{
+erode(hbin, cdfcut = 0.5)
+erode.hexbin(hbin, cdfcut = 0.5)
+}
+
+\arguments{
+ \item{hbin}{an object of class \code{\link{hexbin}}.}
+ \item{cdfcut}{number in (0,1) indicating the confidence level for the
+ limits.}
+}
+
+\value{
+ An \code{"erodebin"} object (with all the slots from \code{hbin}) and
+ additionally with
+ high count cells and a component \code{erode} that gives the erosion order.
+}
+
+\details{
+ The algorithm extracts high count cells with containing a given
+ fraction (cdfcut) of the total counts. The algorithm extracts all
+ cells if cdfcut=0. The algorithm performs gray-level erosion on the
+ extracted cells. Each erosion cycle removes counts from cells. The
+ counts removed for each cell are a multiple of the cell's exposed-face
+ count. The algorithm choses the multiple so at least one cell will be
+ empty or have a count deficit on each erosion cycle. The erode vector
+ contain an erosion number for each cell. The value of erode is
+
+ 6*erosion\_cycle\_ at\_ cell\_ removal - cell\_deficit\_at\_removal
+
+ Cells with low values are eroded first. The cell with the highest
+ erosion number is a candidate bivariate median. A few ties in erode
+ are common.
+}
+
+\seealso{
+ \code{\link{hexbin}}, \code{\link{smooth.hexbin}},
+ \code{\link{hcell2xy}}, %%FIXME\code{\link{hcell}},
+ %% \code{\link{hboxplot}}, \code{\link{hdiffplot}},
+ %% \code{\link{hmatplot}},
+ \code{\link{gplot.hexbin}},
+ \code{\link{grid.hexagons}}, \code{\link{grid.hexlegend}}
+}
+
+\examples{
+set.seed(153)
+x <- rnorm(10000)
+y <- rnorm(10000)
+bin <- hexbin(x,y)
+
+smbin <- smooth.hexbin(bin)
+erodebin <- erode.hexbin(smbin, cdfcut=.5)
+plot(erodebin)
+
+## bivariate boxplot
+hboxplot(erodebin, main = "hboxplot(erodebin)")
+
+
+%% MM: This looks wrong -- both the graphic and the logic in "par" here :
+# show erosion order
+plot(bin,style= "lat", minarea=1, maxarea=1,
+ legend=FALSE, border=gray(.7))
+
+%% FIXME: {compare with example in "hexbin0"}
+grid.hexagons(erodebin,style= "lat", minarea=1, maxarea=1,pen="green")
+xy <- hcell2xy(erodebin)
+library("grid")
+grid.text(lab = as.character(erodebin at erode), xy$x, xy$y,
+ gp = gpar(col="white", cex=0.65))
+
+}
+\keyword{hplot}
diff --git a/man/getHMedian.Rd b/man/getHMedian.Rd
new file mode 100644
index 0000000..447511d
--- /dev/null
+++ b/man/getHMedian.Rd
@@ -0,0 +1,34 @@
+\name{getHMedian}
+\alias{getHMedian}
+\alias{getHMedian,erodebin-method}
+\title{Get coordiantes of the median cell after the erode operation}
+\description{
+ A method for a eroded hexbin object to extract the coordinates of the
+ median cell. The median is simply the cell with the highest erosion
+ number or the last cell to be eroded.
+}
+\usage{
+getHMedian(ebin)
+}
+\arguments{
+ \item{ebin}{result of \code{\link{erode.hexbin}()}.}
+}
+\section{Methods}{
+ \describe{
+ \item{ebin = "erodebin"}{...}
+ }
+}
+\seealso{\code{\link{erode.hexbin}}
+}
+\examples{
+set.seed(153)
+x <- rnorm(10000)
+y <- rnorm(10000)
+bin <- hexbin(x,y)
+
+smbin <- smooth.hexbin(bin)
+erodebin <- erode.hexbin(smbin, cdfcut=.5)
+getHMedian(erodebin)
+}
+\keyword{methods}
+
diff --git a/man/gplot.hexbin.Rd b/man/gplot.hexbin.Rd
new file mode 100644
index 0000000..9db2325
--- /dev/null
+++ b/man/gplot.hexbin.Rd
@@ -0,0 +1,145 @@
+\name{gplot.hexbin}
+\alias{gplot.hexbin}
+\alias{plot,hexbin,missing-method}
+\title{Plotting Hexagon Cells with a Legend}
+\description{
+ Plots Hexagons visualizing the counts in an hexbin object. Different
+ styles are availables. Provides a legend indicating the count
+ representations.
+}
+\usage{
+%% In future: No longer export gplot.hexbin() !
+gplot.hexbin(x, style = "colorscale", legend = 1.2, lcex = 1,
+ minarea = 0.04, maxarea = 0.8, mincnt = 1, maxcnt = max(x at count),
+ trans = NULL, inv = NULL, colorcut = seq(0, 1, length = min(17, maxcnt)),
+ border = NULL, density = NULL, pen = NULL,
+ colramp = function(n) LinGray(n,beg = 90,end = 15),
+ xlab = "", ylab = "", main = "", newpage = TRUE,
+ type = c("p", "l", "n"), xaxt = c("s", "n"), yaxt = c("s", "n"),
+ clip = "on", verbose = getOption("verbose"))
+%% FIXME: This is the S4 plot method for 'hexbin'
+%% currently also exported "standalone" - for testing,debugging..
+%% we'd really don't want to repeat the argument list; use \synopsis{.} ?
+\S4method{plot}{hexbin,missing}(x, style = "colorscale", legend = 1.2, lcex = 1,
+ minarea = 0.04, maxarea = 0.8, mincnt = 1, maxcnt = max(x at count),
+ trans = NULL, inv = NULL, colorcut = seq(0, 1, length = min(17, maxcnt)),
+ border = NULL, density = NULL, pen = NULL,
+ colramp = function(n) LinGray(n,beg = 90,end = 15),
+ xlab = "", ylab = "", main = "", newpage = TRUE,
+ type = c("p", "l", "n"), xaxt = c("s", "n"), yaxt = c("s", "n"),
+ clip = "on", verbose = getOption("verbose"))
+}
+\arguments{
+ \item{x}{an object of class \code{\link{hexbin}}.}
+% \item{y}{(required by the S4 method for \code{\link{plot}} but unused
+% here; must be missing)}
+ \item{style}{string specifying the style of hexagon plot,
+ see \code{\link{grid.hexagons}} for the possibilities.}
+ \item{legend}{numeric width of the legend in inches of \code{FALSE}.
+ In the latter case, or when \code{0}, no legend is not produced.}
+ \item{lcex}{characters expansion size for the text in the legend}
+ \item{minarea}{fraction of cell area for the lowest count}
+ \item{maxarea}{fraction of the cell area for the largest count}
+ \item{mincnt}{cells with fewer counts are ignored.}
+ \item{maxcnt}{cells with more counts are ignored.}
+ \item{trans}{\code{\link{function}} specifying a transformation for
+ the counts such as \code{sqrt}.}
+% FIXME: use better description of these in hexagons() -- or use same
+% ---- help page ?!
+ \item{inv}{the inverse transformation of \code{trans}.}
+ \item{colorcut}{vector of values covering [0, 1] that determine
+ hexagon color class boundaries and hexagon legend size boundaries.
+ Alternatively, an integer (\code{<= maxcnt}) specifying the
+ \emph{number} of equispaced colorcut values in [0,1].}
+ \item{border, density, pen}{color for polygon borders and filling of
+ each hexagon drawn, passed to \code{\link{grid.hexagons}}.}
+ \item{colramp}{function accepting an integer \code{n} as an argument and
+ returning n colors.}
+ \item{xlab, ylab}{x- and y-axis label.}
+ \item{main}{main title.}
+ \item{newpage}{should a new page start?.}
+ \item{type, xaxt, yaxt}{strings to be used (when set to \code{"n"}) for
+ suppressing the plotting of hexagon symbols, or the x- or y-axis,
+ respectively.}
+ \item{clip}{either 'on' or 'off' are the allowed arguments, when on
+ everything is clipped to the plotting region.}
+ \item{verbose}{logical indicating if some diagnostic output should happen.}
+ \item{\dots}{all arguments of \code{gplot.hexbin} can also be used for
+ the S4 \code{\link{plot}} method.}
+}
+\details{
+ This is the (S4) \code{\link{plot}} method for \code{\link{hexbin}} (and
+ \code{erodebin}) objects (\link{erodebin-class}).
+
+ To use the standalone function
+ \code{gplot.hexbin()} is \bold{\emph{deprecated}}.
+ For \code{style}, \code{minarea} etc, see the \bold{Details} section of
+ \code{\link{grid.hexagons}}'s help page.
+
+ The legend functionality is somewhat preliminary. Later versions may
+ include refinements and handle extreme cases (small and large) for
+ cell size and counts.
+}
+\value{
+ invisibly, a list with components
+ \item{plot.vp}{the \code{\link{hexViewport}} constructed and used.}
+ \item{legend.vp}{if a legend has been produced, its
+ \code{\link[grid]{viewport}}.}
+}
+
+\references{ see in \code{\link{grid.hexagons}}.}
+\author{
+ Dan Carr \email{dcarr at voxel.galaxy.gmu.edu},
+ ported by Nicholas Lewin-Koh \email{kohnicho at comp.nus.edu.sg} and
+ Martin Maechler.
+}
+\seealso{\code{\link{hexbin}}, \code{\link{hexViewport}},
+ \code{\link{smooth.hexbin}},
+ \code{\link{erode.hexbin}},
+ \code{\link{hcell2xy}}, \code{\link{hboxplot}},
+ \code{\link{hdiffplot}}. %%, \code{\link{hmatplot}}.
+}
+\examples{
+## 1) simple binning of spherical normal:
+x <- rnorm(10000)
+y <- rnorm(10000)
+bin <- hexbin(x,y)
+
+## Plot method for hexbin !
+## ---- ------ --------
+plot(bin)
+# nested lattice
+plot(bin, style= "nested.lattice")
+
+# controlling the colorscheme
+plot(bin, colramp=BTY, colorcut=c(0,.1,.2,.3,.4,.6,1))
+
+## 2) A mixture distribution
+x <- c(rnorm(5000),rnorm(5000,4,1.5))
+y <- c(rnorm(5000),rnorm(5000,2,3))
+bin <- hexbin(x,y)
+
+pens <- cbind(c("#ECE2F0","#A6BDDB","#1C9099"),
+ c("#FFF7BC","#FEC44F","#D95F0E"))
+plot(bin, style = "nested.lattice", pen=pens)
+# now really crazy
+plot(bin, style = "nested.lattice", pen=pens,border=2,density=35)
+
+# lower resolution binning and overplotting with counts
+bin <- hexbin(x,y,xbins=25)
+P <- plot(bin, style="lattice", legend=FALSE,
+ minarea=1, maxarea=1, border="white")
+##
+%% FIXME!
+library("grid")
+pushHexport(P$plot.vp)
+xy <- hcell2xy(bin)
+ # to show points rather than counts :
+grid.points(x,y,pch=18,gp=gpar(cex=.3,col="green"))
+grid.text(as.character(bin at count), xy$x,xy$y,
+ gp=gpar(cex=0.3, col="red"),default.units="native")
+popViewport()
+
+# Be creative, have fun!
+}
+\keyword{hplot}
diff --git a/man/grid.hexagons.Rd b/man/grid.hexagons.Rd
new file mode 100644
index 0000000..ab9f753
--- /dev/null
+++ b/man/grid.hexagons.Rd
@@ -0,0 +1,199 @@
+\name{grid.hexagons}
+\alias{grid.hexagons}
+\title{Add Hexagon Cells to Plot}
+\description{
+ Plots cells in an hexbin object. The function distinquishes among
+ counts using 5 different styles. This function is the hexagon
+ plotting engine from the \code{plot} method for \code{\link{hexbin}}
+ objects.
+}
+\usage{
+grid.hexagons(dat, style = c("colorscale", "centroids", "lattice",
+ "nested.lattice", "nested.centroids", "constant.col"),
+ use.count=TRUE, cell.at=NULL,
+ minarea = 0.05, maxarea = 0.8, check.erosion = TRUE,
+ mincnt = 1, maxcnt = max(dat at count), trans = NULL,
+ colorcut = seq(0, 1, length = 17),
+ density = NULL, border = NULL, pen = NULL,
+ colramp = function(n){ LinGray(n,beg = 90, end = 15) },
+ def.unit= "native",
+ verbose = getOption("verbose"))
+}
+\arguments{
+ \item{dat}{an object of class \code{hexbin}, see \code{\link{hexbin}}.}
+ \item{style}{character string specifying the type of plotting; must be (a
+ unique abbrevation) of the values given in \sQuote{Usage} above.}
+ \item{use.count}{logical specifying if counts should be used.}
+ \item{cell.at}{numeric vector to be plotted instead of counts, must
+ besame length as the number of cells.}
+ \item{minarea}{numeric, the fraction of cell area for the lowest count.}
+ \item{maxarea}{the fraction of the cell area for the largest count.}
+ \item{check.erosion}{logical indicating only eroded points should be
+ used for \code{"erodebin"} objects; simply passed to
+ \code{\link{hcell2xy}}, see its documentation.}
+ \item{mincnt}{numeric; cells with counts smaller than \code{mincnt}
+ are not shown.}
+ \item{maxcnt}{cells with counts larger than this are not shown.}
+ \item{trans}{a transformation function (or \code{NULL}) for the counts,
+ e.g., \code{\link{sqrt}}.}
+ \item{colorcut}{a vector of values covering [0, 1] which determine
+ hexagon color class boundaries or hexagon size boundaries -- for
+ \code{style = "colorscale"} only.}
+ \item{density}{\code{\link[grid]{grid.polygon}} argument for shading. 0 causes
+ the polygon not to be filled. \emph{This is not implemented (for
+ \code{\link[grid]{grid.polygon}}) yet}.}
+ \item{border}{\code{\link[grid]{grid.polygon}()} argument. Draw the border for
+ each hexagon.}
+ \item{pen}{colors for \code{\link[grid]{grid.polygon}()}. Determines the color
+ with which the polygon will be filled.}
+ \item{colramp}{function of an integer argument \code{n} returning n
+ colors. \code{n} is determined }%% how? FIXME
+ \item{def.unit}{default \code{\link[grid]{unit}} to be used.}% FIXME
+ \item{verbose}{logical indicating if some diagnostic output should happen.}
+}
+\section{SIDE EFFECTS}{Adds hexagons to the plot.}
+
+\details{
+ The six plotting styles have the following effect:
+ \describe{
+ \item{\code{style="lattice"} or \code{"centroids"}:}{
+
+ Plots the hexagons in different sizes based on counts. The
+ \code{"lattice"} version centers the hexagons at the cell centers
+ whereas \code{"centroids"} moves the hexagon centers close to the
+ center of mass for the cells. In all cases the hexagons will not
+ plot outside the cell unless \code{maxarea > 1}. Counts are rescaled
+ into the interval [0,1] and colorcuts determine the class
+ boundaries for sizes and counts. The pen argument for this style
+ should be a single color or a vector of colors of
+ \code{length(bin at count)}.}
+
+ \item{\code{style="colorscale"}:}{
+ Counts are rescaled into the interval [0,1] and colorcuts determines
+ the class boundaries for the color classes. For this style, the
+ function passed as \code{colramp} is used to define the n colors for
+ the n+1 color cuts. The pen argument is ignored.
+ %% S-plus: In motif color options try polygon: black 16 white
+ See \code{\link{LinGray}} for the default \code{colramp} and
+ alternative \dQuote{color ramp} functions.
+ }
+ \item{\code{style="constant.col"}:}{
+ This is an even simpler alternative to \code{"colorscale"},
+ using constant colors (determined \code{pen} optionally).
+ }
+
+ \item{\code{style="nested.lattice"} and \code{"nested.centroids"}:}{
+ Counts are partitioned into classes by power of 10. The encoding
+ nests hexagon size within powers of 10 color contours.
+
+ If the pen argument is used it should be a matrix of colors with 2
+ columns and either \code{ceiling(log10(max(bin at count)))} or
+ \code{length(bin at count)} rows. The default uses the \R color palatte
+ so that pens numbers 2-11 determine colors for completely filled
+ cell Pen 2 is the color for 1's, Pen 3 is the color for 10's, etc.
+ Pens numbers 12-21 determine the color of the foreground hexagons. The
+ hexagon size shows the relative count for the power of 10. Different
+ color schemes give different effects including 3-D illusions
+ %% S-plus :
+ %% One motif color option for the first 4 powers is black \#BBB \#36F
+ %% \#0E3 \#F206 \#FFF4 \#FFF
+ %%
+ %% A second option is for the first 5 power is black \#FFF \#08F \#192
+ %% \#F11 \#FF04 \#000 \#999 \#5CF \#AFA \#FAAF \#000
+ }
+ }
+
+ \emph{Hexagon size encoding \code{minarea} and \code{maxarea}}
+ determine the area of the smallest and largest hexagons
+ plotted. Both are expressed fractions of the bin cell size. Typical
+ values might be .04 and 1. When both values are 1, all plotted
+ hexagons are bin cell size, if \code{maxarea} is greater than 1 than
+ hexagons will overlap. This is sometimes interesting with the lattice
+ and centroid styles.
+
+ \emph{Count scaling}
+
+ \code{relcnt <- (trans(cnt)-trans(mincnt)) / (trans(maxcnt)-trans(mincnt))}
+ \cr
+ \code{area <- minarea + relcnt*maxarea}
+
+ By default the transformation \code{trans()} is the identity
+ function. The legend routine requires the transformation inverse
+ for some options.
+
+ \emph{Count windowing \code{mincnt} and \code{maxcnt}}
+ Only routine only plots cells with cnts in [mincnts, maxcnts]
+}
+\references{
+ Carr, D. B. (1991)
+ Looking at Large Data Sets Using Binned Data Plots,
+ pp. 7--39 in \emph{Computing and Graphics in Statistics};
+ Eds. A. Buja and P. Tukey, Springer-Verlag, New York.
+}
+\author{
+ Dan Carr <dcarr at voxel.galaxy.gmu.edu>;
+ ported and extended by Nicholas Lewin-Koh \email{nikko at hailmail.net}.
+}
+\seealso{\code{\link{hexbin}}, \code{\link{smooth.hexbin}},
+ \code{\link{erode.hexbin}}, \code{\link{hcell2xy}},% \code{\link{hcell}},
+ \code{\link{gplot.hexbin}}, \code{\link{hboxplot}}, \code{\link{hdiffplot}},
+ \code{\link{grid.hexlegend}}% \code{\link{hmatplot}}
+}
+
+\examples{
+set.seed(506)
+x <- rnorm(10000)
+y <- rnorm(10000)
+
+# bin the points
+bin <- hexbin(x,y)
+
+# Typical approach uses plot( <hexbin> ) which controls the plot shape :
+plot(bin, main = "Bivariate rnorm(10000)")
+
+## but we can have more manual control:
+
+# A mixture distribution
+x <- c(rnorm(5000),rnorm(5000,4,1.5))
+y <- c(rnorm(5000),rnorm(5000,2,3))
+hb2 <- hexbin(x,y)
+
+# Show color control and overplotting of hexagons
+## 1) setup coordinate system:
+P <- plot(hb2, type="n", main = "Bivariate mixture (10000)")# asp=1
+
+## 2) add hexagons (in the proper viewport):
+pushHexport(P$plot.vp)
+grid.hexagons(hb2, style= "lattice", border = gray(.1), pen = gray(.6),
+ minarea = .1, maxarea = 1.5)
+library("grid")
+popViewport()
+
+## How to treat 'singletons' specially:
+P <- plot(hb2, type="n", main = "Bivariate mixture (10000)")# asp=1
+pushHexport(P$plot.vp)
+grid.hexagons(hb2, style= "nested.centroids", mincnt = 2)# not the single ones
+grid.hexagons(hb2, style= "centroids", maxcnt = 1, maxarea=0.04)# single points
+popViewport()
+
+
+%% FIXME --- this would mix grid- and traditional-graphics
+%% ----- would need grid-graphics for 'gpclib' -- aaargs...
+% # And if we had all the information...
+% if(require(gpclib)){
+% h1 <- chull(x[1:5000], y[1:5000])
+% h2 <- chull(x[5001:10000], y[5001:10000])
+% h2 <- h2+5000
+% h1 <- as(cbind(x[1:5000],y [1:5000])[h1, ], "gpc.poly")
+% h2 <- as(cbind(x,y)[h2, ], "gpc.poly")
+% plot(hb2, type="n", main = "Bivariate mixture (10000)")# asp=1
+%
+% plot(h1,poly.args = list(col ="#CCEBC5"),add = TRUE)
+% plot(h2,poly.args = list(col ="#FBB4AE"),add = TRUE)
+% plot(intersect(h1, h2), poly.args = list(col = 2), add = TRUE)
+% grid.hexagons(hb2, style= "centroids", border = gray(.1), pen = gray(.6),
+% minarea = .1, maxarea = 1.5)
+% }
+
+}
+\keyword{aplot}
diff --git a/man/grid.hexlegend.Rd b/man/grid.hexlegend.Rd
new file mode 100644
index 0000000..991d005
--- /dev/null
+++ b/man/grid.hexlegend.Rd
@@ -0,0 +1,81 @@
+\name{grid.hexlegend}
+\alias{grid.hexlegend}
+\title{Add a Legend to a Hexbin Plot}
+\description{
+ Plots the legend for the \code{plot} method of \code{\link{hexbin}}.
+ Provides a legend indicating the count representations.
+}
+\usage{
+grid.hexlegend(legend, ysize, lcex, inner, style = ,
+ minarea = 0.05, maxarea = 0.8, mincnt = 1, maxcnt, trans = NULL,
+ inv = NULL, colorcut, density = NULL, border = NULL, pen = NULL,
+ colramp = function(n) { LinGray(n,beg = 90,end = 15) },
+ leg.unit = "native")
+}
+\arguments{
+ \item{legend}{positive number giving width of the legend in inches.}
+ \item{ysize}{height of legend in inches}
+ \item{lcex}{the characters expansion size for the text in the legend,
+ see \code{\link{par}(cex=)}.}
+ \item{inner}{the inner diameter of a hexagon in inches.}
+ \item{style}{the hexagon style; see \code{\link{grid.hexagons}}.}
+ \item{minarea, maxarea}{fraction of the cell area for the lowest and largest
+ count, respectively.}
+ \item{mincnt, maxcnt}{minimum and maximum count accepted in \code{plot}.}
+ \item{trans}{a transformation function for the counts such as
+ \code{\link{sqrt}}.}
+ \item{inv}{the inverse transformation function.}
+ \item{colorcut}{numeric vector of values covering [0, 1] the determine
+ hexagon color classes boundaries and hexagon legend size boundaries.}
+ \item{border}{argument for \code{\link{polygon}()}. Draw the border
+ for each hexagon.}
+ \item{density}{argument for \code{\link{polygon}()} filling. A
+ \code{0} causes the polygon not to be filled.}
+ \item{pen}{color argument used for \code{\link{polygon}(col = .)}.
+ Determines the color with which the polygon will be filled.}
+ \item{colramp}{function accepting an integer \code{n} as an argument and
+ returning n colors.}
+ \item{leg.unit}{unit to use}%FIXME
+
+}
+\details{
+ The \code{plot} method for \code{\link{hexbin}} objects calls this function
+ to produce a legend
+ by setting the graphics parameters, so \code{hex.legend} itself is not a
+ standalone function.
+
+ The legend function is \bold{preliminary}. Later version will include
+ refinements and handle extreme cases (small and large) for cell size
+ and counts.
+
+ See the \bold{Details} section of \code{\link{grid.hexagons}}'s help page.
+}
+\value{
+ This function does not return any value.
+}
+\references{ see in \code{\link{grid.hexagons}}.}
+\author{
+ Dan Carr <dcarr at voxel.galaxy.gmu.edu>
+
+ ported by Nicholas Lewin-Koh <kohnicho at comp.nus.edu.sg>
+}
+
+\seealso{\code{\link{hexbin}}, \code{\link{grid.hexagons}},
+% FIXME
+ \code{\link{smooth.hexbin}}, \code{\link{erode.hexbin}},
+% \code{\link{hcell}},
+ \code{\link{hcell2xy}},
+ \code{\link{gplot.hexbin}},% \code{\link{hboxplot}},% \code{\link{hdiffplot}},
+% \code{\link{hmatplot}}
+}
+
+\examples{
+## Not a stand alone function; typically only called from plot.hexbin()
+%% Hence we should not run it here!
+%% FIXME: Improve hex.legend() such that it *can* be added to plots !!!
+\dontrun{
+ grid.hexlegend(legend = 2, ysize = 1,lcex=8,inner=0.2,
+ maxcnt = 100, colorcut = c(0.5,0.5))
+}
+}
+\keyword{aplot}
diff --git a/man/hboxplot.Rd b/man/hboxplot.Rd
new file mode 100644
index 0000000..1454601
--- /dev/null
+++ b/man/hboxplot.Rd
@@ -0,0 +1,98 @@
+\name{hboxplot}
+\alias{hboxplot}
+\title{2-D Generalization of Boxplot}
+
+\description{
+ If \code{bin} is an \emph{eroded} \code{\link{hexbin}} object, i.e.,
+ an \code{erodebin} object, \code{hboxplot()} plots the high counts cells
+ selected by \code{\link{erode}()}. By default, the high counts
+ cells contain 50 percent of the counts so analagous to the
+ interquartile \dQuote{range}. The function distinguishes the last
+ cells eroded using color. These cells correspond to one definition of the
+ bivariate median.
+%% FIXME ^^ (bad style, content +- ok)
+}
+
+\usage{
+hboxplot(bin, xbnds = NULL, ybnds = NULL,
+ density, border = c(0, grey(0.7)), pen = c(2, 3),
+ unzoom = 1.1, clip ="off", reshape = FALSE,
+ xlab = NULL, ylab = NULL, main = "")
+}
+\arguments{
+ \item{bin}{an object of class \code{\link{hexbin}}.}
+ \item{xbnds,ybnds}{global x- and y-axis plotting limits for multiple
+ plots.}
+ \item{density, border}{arguments for \code{\link{polygon}()} each of
+ length two, the first for the median, the second for the other cells.}
+ \item{pen}{colors (\dQuote{pen numbers}) for \code{polygon()}.}
+ \item{unzoom}{plot limit expansion factor when \code{xbnds} is
+ missing.}
+ \item{clip}{either 'on' or 'off' are the allowed arguments, when on
+ everything is clipped to the plotting region.}
+ \item{reshape}{logical value to reshape the plot although \code{xbnds}
+ and \code{ybnds} are present.}
+ \item{xlab, ylab, main}{x- and y- axis labels and main title}
+}
+
+\value{
+ invisibly, the \code{\link{hexViewport}()} used internally.
+ Used to add to the plot afterwards.
+}
+
+\references{ see in \code{\link{grid.hexagons}}.}
+
+\details{
+ The \code{density}, \code{border}, and \code{pen} arguments correspond
+ to the \code{\link{polygon}} function calls for plotting two types of
+ cells. The cell types, pen numbers and suggested colors are\cr
+ \tabular{lll}{
+ TYPE \tab PEN \tab COLOR \cr
+ cells of bin \tab 2 \tab light gray \cr
+ last eroded cells of bin (median cells)\tab 1 \tab black \cr
+ }
+
+ The erode components of the hexbin objects must be present for the
+ medians cells to plot.
+
+ When \code{xbnds} is missing or \code{reshape} is true, the plot
+ changes graphics parameters and resets them. When \code{xbnds} is
+ missing the function also zooms in based on the available data to
+ provide increased resolution.
+
+ The zoom used the hexagon cell centers. The unzoom argument backs off
+ a bit so the whole hexagon will fit in the plot.
+
+ \code{Hboxplot()} is used as a stand alone function, for producing separate
+ legends .....%%FIXME for \code{\link{hmatplot}()} and for panels in
+ %% \code{\link{hmatplot}()}.
+}
+
+\seealso{
+ \code{\link{hexbin}}, \code{\link{erode}},
+ %\code{\link{smooth.hexbin}},
+ \code{\link{hcell2xy}},% \code{\link{hcell}},
+ \code{\link{gplot.hexbin}},
+% \code{\link{hmatplot}},
+ \code{\link{grid.hexagons}}, \code{\link{grid.hexlegend}}
+}
+
+\examples{
+\dontshow{set.seed(753)}
+## boxplot of smoothed counts
+x <- rnorm(10000)
+y <- rnorm(10000)
+
+bin <- hexbin(x,y)
+erodebin <- erode(smooth.hexbin(bin))
+
+hboxplot(erodebin)
+hboxplot(erodebin, density = c(32,7), border = c(2,4))
+hp <- hboxplot(erodebin, density = c(-1,17),
+ main = "hboxplot(erode*(smooth*(.)))")
+pushHexport(hp)
+library("grid")
+grid.points(x[1:10], y[1:10])# just non-sense to show the principle
+popViewport()
+}
+\keyword{hplot}
diff --git a/man/hcell2xy.Rd b/man/hcell2xy.Rd
new file mode 100644
index 0000000..83c926b
--- /dev/null
+++ b/man/hcell2xy.Rd
@@ -0,0 +1,63 @@
+\name{hcell2xy}
+\alias{hcell2xy}
+\alias{hcell2xy,hexbin-method}
+
+\title{Compute X and Y Coordinates for Hexagon Cells}
+
+\description{
+ Computes x and y coordinates from hexagon cell id's.
+}
+\usage{
+hcell2xy(hbin, check.erosion = TRUE)
+}
+\arguments{
+ \item{hbin}{a object of class \code{"hexbin"}, typically produced by
+ \code{\link{hexbin}(*)}.}
+ \item{check.erosion}{logical indicating if only the eroded points
+ should be returned in the case where \code{hbin} inherits from
+ \code{"erodebin"} (see \code{\link{erodebin-class}}); is \code{TRUE}
+ by default.}
+}
+\value{
+ A list with two components of the same length as \code{bin$cell},
+ \item{x}{}
+ \item{y}{}
+}
+
+%%FIXME \references{see in \code{\link{hcell}}.}
+
+\details{
+ The hexbin object \code{hbin} contains all the needed information.
+ The purpose of this function is to reduce storage. The cost is
+ additional calculation.
+}
+
+\seealso{%%FIXME \code{\link{hcell}}, \code{\link{hray}},
+ \code{\link{hexbin}}.
+}
+
+\examples{
+x <- rnorm(10000)
+y <- rnorm(10000)
+plot(x,y, pch=".")
+hbin <- hexbin(x,y)
+str(xys <- hcell2xy(hbin))
+points(xys, cex=1.5, col=2) ; title("hcell2xy( hexbin(..) )", col.main=2)
+
+%% __________ FIXME ________
+\dontshow{
+## Temporal trends with confidence bounds plotted on a map:
+## <NOT YET> Illustration only pending access to user functions
+## mtapply() # like tapply but for matrices
+## sens.season.slope() # computes sen's seasonal slope
+
+## This part does not work and commented out
+#hbin <- hcell(dat$x,dat$y) # x and y are in map projection units
+#newdat < dat[,c('month','year','value')] # extract columns
+#stats <- mtapply(newdat,bin$cell,sens.season.slope,season=12)
+#plot(mymap,type='l') # map boundaries in map projection units
+#xy <- hcell2xy(hbin) # x and y coordinates for hexagon cell centers
+#hray(xy$x, xy$y,val=stat[,1],lower= stat[,2],upper=stat[,3])
+}
+}
+\keyword{manip}
diff --git a/man/hcell2xyInt.Rd b/man/hcell2xyInt.Rd
new file mode 100644
index 0000000..93ac7e0
--- /dev/null
+++ b/man/hcell2xyInt.Rd
@@ -0,0 +1,47 @@
+\name{hcell2xyInt}
+\alias{hcell2xyInt}
+%- Also NEED an '\alias' for EACH other topic documented here.
+\title{Change cell ids to 2d integer coordinate system}
+\description{
+ Transforms the cell representation of a a lattice into a 2d integer
+ coordinate system.
+}
+\usage{
+ hcell2xyInt(hbin, xbins=NULL, xbnds=NULL, ybnds=NULL, shape=NULL)
+}
+
+\arguments{
+ \item{hbin}{a object of class \code{"hexbin"}, typically produced by
+ \code{\link{hexbin}(*)}.}
+ \item{xbins}{the number of bins partitioning the range of xbnds.}
+ \item{xbnds, ybnds}{horizontal and vertical limits of the binning
+ region in x or y units respectively; must be numeric vector of
+ length 2.}
+ \item{shape}{the \emph{shape} = yheight/xwidth of the plotting regions.}
+
+}
+\details{
+ Takes a grid defined by either the hexbin parameters or dimen in a
+ hexbin object and translates the cell ids for the grid into 2d integer
+ coordinates.
+}
+\value{
+ An integer matrix with two columns, i and j representing the integer
+ xy coordinates of the hexagon grid.
+ \item{i}{Integer coordiante of the rows, increases from bottom to top}
+ \item{j}{Integer coordiante of the columns, increases from left to right}
+}
+
+\author{Nicholas Lewin-Koh }
+
+
+\seealso{\code{\link{hcell2xy}}}
+\examples{
+ x<-rnorm(10000)
+ y<-rnorm(10000)
+ hbin<-hexbin(x,y)
+ ijInt<-hcell2xyInt(hbin)
+}
+
+\keyword{dplot}
+\keyword{misc}
diff --git a/man/hdiffplot.Rd b/man/hdiffplot.Rd
new file mode 100644
index 0000000..3461019
--- /dev/null
+++ b/man/hdiffplot.Rd
@@ -0,0 +1,134 @@
+\name{hdiffplot}
+\alias{hdiffplot}
+\title{Plot of Domain and Median Differences of Two "hexbin" Objects}
+\description{
+ Let \code{bin1} and \code{bin2} represent two \code{\link{hexbin}}
+ objects with scaling, plot shapes, and bin sizes. This plot
+ distinguishes cells unique to \code{bin1}, cells in common, and cells
+ unique to \code{bin2} using color. When the erode components are
+ present, color also distinguishes the two erosion medians. An arrow
+ shows the vector from the median of \code{bin1} to the median of
+ \code{bin2}.
+}
+\usage{
+hdiffplot(bin1, bin2 = NULL, xbnds, ybnds,
+ focus = NULL,% if(is.null(bin2)) 1:length(bin1) else c(1, 2),
+ col.control = list(medhex = "white", med.bord = "black",
+ focus = NULL, focus.border = NULL, back.col = "grey"),
+ arrows = TRUE, size = unit(0.1, "inches"), lwd = 2,
+ eps = 1e-6, unzoom = 1.08, clip="off", xlab = "", ylab = "",
+ main = deparse(mycall), \dots)
+}
+
+\arguments{
+ \item{bin1, bin2}{two objects of class \code{\link{hexbin}}.}
+ \item{xbnds,ybnds}{global x- and y-axis plotting limits. Used
+ primarily for multiple comparison plots.}
+%%%------- FIXME --------
+ \item{focus}{a vector of integers specifying which hexbin objects
+ should be treated as focal. Excluded hexbins are treated as background.}
+ \item{col.control}{a list for detailed color control.}%% <<< FIXME
+ \item{arrows}{a logical indicating wheter or not to draw arrows
+ between the focal hexbin objects median cells.}
+%not yet \item{density}{fill arguments to polygon}
+%not yet \item{pen}{pen numbers for polgyon}
+ \item{border}{border arguments to polygon}
+ \item{size}{arrow type size in inches.}
+ \item{eps}{distance criteria for distinct medians}
+ \item{unzoom}{plot limit expansion factor when xbnds is missing}
+ \item{clip}{either 'on' or 'off' are the allowed arguments, when on
+ everything is clipped to the plotting region.}
+ \item{lwd}{Line width for arrows, ignored when \code{arrows=FALSE} or
+ when bins have no erosion component}
+ \item{xlab}{label for x-axis}
+ \item{ylab}{label for y-axis}
+ \item{main}{main title for the plot; automatically constructed by default.}
+ \item{\dots}{...............}
+}
+
+% \value{
+% ((currently unspecified --- proposals are welcome))%% FIXME
+% }
+
+\details{
+ The hexbin objects for comparison, \code{bin1} and \code{bin2}, must
+ have the same plotting limits and cell size. The plot produces a
+ comparison overlay of the cells in the two objects. If external
+ global scaling is not supplied, the algorithm determines plotting
+ limits to increase resolution. For example, the objects may be the
+ result of the \code{\link{erode.hexbin}()} and include only high count cells
+ containing 50 of the counts. The density, border, and pen arguments
+ correspond to the polygon function calls for plotting six types of
+ cells. The cell types are respectively:
+ \tabular{l}{
+ unique cells of bin1,\cr
+ joint cells,\cr
+ unique cells of bin2,\cr
+ median cell of bin1,\cr
+ median cell of bin2,\cr
+ median cell if identical.\cr
+ }
+
+ The \code{erode} components of the hexbin objects must be present for the
+ medians to plot. The algorithm select a single cell for the median if
+ there are algorithmic ties.
+
+%% FIXME: no 'pen' argument anymore .. (?)
+ The \code{pen} numbers for types of cells start at Pen 2. Pen 1 is
+ presumed black. The suggested six additional colors are light blue,
+ light gray, light red, blue, red, and black. Carr (1991) shows an
+ example for black and white printing. That plot changes the six
+ colors to light gray, dark gray, white, black, black, and black. It
+ changes the 4th, 5th, and 6th argument of border to TRUE. It also
+ changes 4th, 5th and 6th argument of density to 0. In other words
+ cells in common do not show and medians cells appear as outlines.
+
+ When \code{xbnds} is missing, the plot changes graphics parameters and
+ resets them. The function also zooms in based on the available data
+ to provide increased resolution.
+}
+
+\references{ see in \code{\link{grid.hexagons}}.}%>> ./hexagons.Rd
+
+\seealso{
+ \code{\link{hexbin}}, \code{\link{smooth.hexbin}}, \code{\link{erode.hexbin}},
+ % MISSING: hthin,
+ \code{\link{hcell2xy}}, % \code{\link{hcell}},
+ \code{\link{gplot.hexbin}},
+ \code{\link{hboxplot}}, % \code{\link{hmatplot}},
+ \code{\link{grid.hexagons}}, \code{\link{grid.hexlegend}}.
+}
+\examples{
+## Comparison of two bivariate boxplots
+x1 <- rnorm(10000)
+y1 <- rnorm(10000)
+x2 <- rnorm(10000,mean=.5)
+y2 <- rnorm(10000,mean=.5)
+xbnds <- range(x1,x2)
+ybnds <- range(y1,y2)
+
+bin1 <- hexbin(x1,y1,xbnds=xbnds,ybnds=ybnds)
+bin2 <- hexbin(x2,y2,xbnds=xbnds,ybnds=ybnds)
+erodebin1 <- erode.hexbin(smooth.hexbin(bin1))
+erodebin2 <- erode.hexbin(smooth.hexbin(bin2))
+
+hdiffplot(erodebin1,erodebin2)
+
+## Compare *three* of them: --------------------
+
+x3 <- rnorm(10000,mean=-1)
+y3 <- rnorm(10000,mean=-.5)
+xbnds <- range(x1,x2,x3)
+ybnds <- range(y1,y2,y3)
+
+bin1 <- hexbin(x1,y1,xbnds=xbnds,ybnds=ybnds)
+bin2 <- hexbin(x2,y2,xbnds=xbnds,ybnds=ybnds)
+bin3 <- hexbin(x3,y3,xbnds=xbnds,ybnds=ybnds)
+erodebin1 <- erode.hexbin(smooth.hexbin(bin1))
+erodebin2 <- erode.hexbin(smooth.hexbin(bin2))
+erodebin3 <- erode.hexbin(smooth.hexbin(bin3))
+
+bnlst <- list(b1=erodebin1, b2=erodebin2, b3=erodebin3)
+hdiffplot(bnlst)
+}
+\keyword{hplot}
diff --git a/man/hexGraphPaper.Rd b/man/hexGraphPaper.Rd
new file mode 100644
index 0000000..3da2c0c
--- /dev/null
+++ b/man/hexGraphPaper.Rd
@@ -0,0 +1,66 @@
+\name{hexGraphPaper}
+\alias{hexGraphPaper}
+\alias{hgridcent}
+\title{Create a Hexgon Grid}
+\description{
+ Creates a hexagon grid that can be added to a plot created with grid
+ graphics.
+}
+\usage{
+hexGraphPaper(hb, xbnds = NULL, ybnds = NULL, xbins = 30, shape = 1,
+ add = TRUE, fill.edges = 1, fill = 0, border = 1)
+
+hgridcent(xbins, xbnds, ybnds, shape, edge.add = 0)
+}
+\arguments{
+ \item{hb}{a object of class \code{"hexbin"}, typically produced by
+ \code{\link{hexbin}(*)}.}
+ \item{xbnds, ybnds}{horizontal and vertical limits of the binning
+ region in x or y units respectively; must be numeric vector of
+ length 2.}
+ \item{xbins}{the number of bins partitioning the range of xbnds.}
+ \item{shape}{the \emph{shape} = yheight/xwidth of the plotting regions.}
+ \item{add}{a logical value indicating whether or not to add the grid
+ to the current plot.}
+ \item{fill.edges}{integer number of hexagons to add around the border}
+ \item{fill}{the fill color for the hexagons}
+ \item{border}{the color of the border of the hexagons}
+ \item{edge.add}{offset (typically \code{fill.edges} above) used in
+ \code{hgridcent}.}
+}
+\details{
+ If a hexbin object is given then the parameters xbins and shape are
+ ignored. Different bounds can still be specified. The \code{fill.edges}
+ parameter should be an integer. \code{fill.edges} takes the current
+ grid and adds a layer of hexagons around the grid for each level of
+ fill. So for example if \code{fill.edges= 2} than the dimensions of
+ the grid would be \code{(i,j)+4}.
+
+ \code{hgridcent()} is the utility function computing the resulting
+ list (see section \dQuote{Value}).
+
+ \strong{WARNING! If using a hexVP be sure to set clip to "on", otherwise the
+ hexagon grid will bleed over the plot edges.}
+}
+\value{
+ Invisibly returns a list with th following components
+ \item{x}{The x coordinates of the grid}
+ \item{y}{the y coordinates of the grid}
+ \item{dimen}{a vector of length 2 gining the rows and columns of the grid}
+ \item{dx}{the horizontal diameter of the hexagons}
+ \item{dy}{the vertical diameter of the hexagons}
+}
+\author{Nicholas Lewin-Koh}
+\seealso{\code{\link{hcell2xy}}, \code{\link{hexpolygon}},
+ \code{\link{grid.hexagons}}}
+\examples{
+ x <- rnorm(10000)
+ y <- rnorm(10000,x,x)
+ hbin <- hexbin(x,y)
+ hvp <- plot(hbin,type="n")
+ pushHexport(hvp$plot,clip="on")
+ hexGraphPaper(hbin,border=grey(.8))
+ grid.hexagons(hbin)
+}
+\keyword{aplot}
+\keyword{dplot}
diff --git a/man/hexList.Rd b/man/hexList.Rd
new file mode 100644
index 0000000..7add00f
--- /dev/null
+++ b/man/hexList.Rd
@@ -0,0 +1,46 @@
+\name{hexList}
+\alias{hexList}
+\alias{hexbinList-class}
+\alias{coerce,list,hexbinList-method}
+\title{Conditional Bivariate Binning into Hexagon Cells }
+\description{
+ Creates a list of \code{\link{hexbin}} objects. Basic components are
+ a cell id and a count of points falling in each occupied cell.
+ Basic methods are \code{\link[methods]{show}()}, \code{plot()} %(\link{plot.hexbin})
+ and \code{\link{summary}()}, but also \code{\link{erode}}.
+ % .. \code{\link{smooth.hexbin}}
+}
+\usage{
+hexList(x, y = NULL, given = NULL, xbins = 30, shape = 1,
+ xbnds = NULL, ybnds = NULL, xlab = NULL, ylab = NULL)
+}
+%- maybe also 'usage' for other objects documented here.
+\arguments{
+ \item{x}{ x coordinate to be binned }
+ \item{y}{ y coordinate to be binned }
+ \item{given}{ ..}
+ \item{xbins}{ number of bins partitioning the range of xbnds}
+ \item{shape}{ the \emph{shape} = yheight/xwidth of the plotting regions }
+ \item{xbnds}{ horizontal limits of binning }
+ \item{ybnds}{ vertical limits of binning }
+ \item{xlab}{ character strings used as labels for \code{x} }
+ \item{ylab}{ character strings used as labels for \code{y}}
+}
+\details{
+ There is also a \code{\link[methods:as]{coerce}} method to produce
+ \code{hexbinList} objects from \code{\link{list}}s.
+ %% i.e., \code{as(list(....), "hexbinList")} should work
+}
+\value{
+
+ If it is a LIST, use
+ \item{comp1 }{Description of 'comp1'}
+ \item{comp2 }{Description of 'comp2'}
+ ...
+}
+
+\author{Nicholas Lewin-Koh}
+
+\seealso{\code{\link{hexbin}}, \code{\link{hdiffplot}} }
+\keyword{dplot}
+\keyword{misc}
diff --git a/man/hexMA.loess.Rd b/man/hexMA.loess.Rd
new file mode 100644
index 0000000..4f25d19
--- /dev/null
+++ b/man/hexMA.loess.Rd
@@ -0,0 +1,42 @@
+\name{hexMA.loess}
+\alias{hexVP.loess}
+\alias{hexMA.loess}
+\title{Add Loess Fit to Hexplot }
+\description{
+ Fit a loess line using the hexagon centers of mass as the x and y
+ coordinates and the cell counts as weights.
+}
+\usage{
+hexMA.loess(pMA, span = 0.4, col = "red", n = 200)
+hexVP.loess(hbin, hvp = NULL, span = 0.4, col = "red", n = 200)
+}
+
+\arguments{
+ \item{hbin}{an object of class \code{hexbin}, see \code{\link{hexbin}}.}
+ \item{hvp}{A \code{hexViewport} object.}
+ \item{pMA}{the list returned by \code{\link{plotMAhex}}.}
+ \item{span}{the parameter alpha which controls the degree of smoothing.}
+ \item{col}{line color for the loess fit.}
+ \item{n}{number of points at which the fit should be evaluated.}
+}
+\value{
+ Returns invisibly the object associated with the loess fit.
+}
+
+\author{Nicholas Lewin-Koh }
+
+\seealso{ \code{\link{hexVP.abline}}, \code{\link{plotMAhex}},
+ \code{\link{gplot.hexbin}}, \code{\link{hexViewport}};
+ \code{\link{loess}}
+}
+\examples{
+ if(require(marray)){
+ data(swirl)
+ %% the following had 'newpage = FALSE, ' -- why ??
+ hb <- plotMAhex(swirl[,1], main = "M vs A plot with hexagons", legend=0)
+ hexVP.abline(hb$plot, h=0, col= gray(.6))
+ hexMA.loess(hb)
+ }
+}
+\keyword{aplot}
+
diff --git a/man/hexTapply.Rd b/man/hexTapply.Rd
new file mode 100644
index 0000000..159b624
--- /dev/null
+++ b/man/hexTapply.Rd
@@ -0,0 +1,58 @@
+\name{hexTapply}
+\alias{hexTapply}
+
+\title{Apply function to data from each hexagon bin.}
+
+\description{
+ A wrapper for tapply except that it operates with each hexagon bin
+ being the category. The function operates on the data associated on
+ the points from each bin.
+}
+
+\usage{
+hexTapply(hbin, dat, FUN = sum, ..., simplify=TRUE)
+}
+\arguments{
+ \item{hbin}{a object of class \code{"hexbin"}, typically produced by
+ \code{\link{hexbin}(*)}.}
+ \item{dat}{A vector of data the same length as \code{hbin at cID}}
+ \item{FUN}{the function to be applied. In the case of functions like
+ \code{+}, \code{\%*\%}, etc., the function name must be quoted. If
+ \code{FUN} is \code{NULL}, tapply returns a vector which can be used
+ to subscript the multi-way array \code{tapply} normally produces.}
+ \item{\dots}{optional arguments to \code{FUN}.}
+ \item{simplify}{If \code{FALSE}, \code{tapply} always returns an array
+ of mode \code{"list"}. If \code{TRUE} (the default), then if
+ \code{FUN} always returns a scalar, \code{tapply} returns an array
+ with the mode of the scalar.}
+}
+\details{
+ This function is a wrapper for tapply, except that the cell id is
+ always the categorical variable. This function is specifically good for
+ adding variables to the cAtt slot of a hexbin object or for plotting
+ a third variable in a hexagon plot. See below for examples.
+}
+
+\value{
+ Returns a vector of the result of 'FUN' as in
+ \code{\link{tapply}}. See \code{\link{tapply}} for detailed
+ description of output.
+}
+
+\author{Nicholas Lewin-Koh}
+\seealso{ \code{\link{tapply}},\code{\link{hexbin}} }
+\examples{
+ data(NHANES)
+ hbin<-hexbin(log(NHANES$Diet.Iron+1),log(NHANES$BMI),xbins=25,IDs=TRUE)
+ hvp<-plot(hbin)
+ mtrans<-hexTapply(hbin,NHANES$Transferin,median,na.rm=TRUE)
+ pushHexport(hvp$plot.vp)
+ grid.hexagons(hbin,style='lattice',pen=0,border='red',use.count=FALSE,
+cell.at=mtrans)
+
+
+
+}
+\keyword{dplot}
+\keyword{utilities}% at least one, from doc/KEYWORDS
+
diff --git a/man/hexVP-class.Rd b/man/hexVP-class.Rd
new file mode 100644
index 0000000..306c6d5
--- /dev/null
+++ b/man/hexVP-class.Rd
@@ -0,0 +1,76 @@
+\name{hexVP-class}
+\docType{class}
+\alias{hexVP-class}
+\alias{getFig,hexVP-method}
+\alias{getMargins,hexVP-method}
+\alias{getPlt,hexVP-method}
+\alias{getXscale,hexVP-method}
+\alias{getYscale,hexVP-method}
+
+\title{Formal class "hexVP" of a Hexagon Viewport}
+\description{
+ Hexagon Viewports are \dQuote{value-added} grid viewports (see
+ \code{\link[grid]{viewport}}) where the extra slots contain scaling and
+ \dQuote{embedding} information. A hexViewport is created my taking the
+ available area in the cuurent viewport on the graphics device and
+ maximizing the amount of area with a fied aspect ratio. The default
+ when the shape parameter is 1, is a 1:1 aspect ratio in terms of the
+ size of the viewport, not the scale of the x and y axis. The plotting
+ area is centered within the existing margins and the maximum size
+ determined. Extra area is then allocated to the margins. This viewport
+ is replicated twice, once with clipping set to "on" and once with
+ clipping "off". This feature can be used for toggling clipping on and
+ off while editing the plot.
+}
+\section{Objects from the Class}{
+ Objects are typically created by calls to \code{\link{hexViewport}()}
+ or by low level calls of the form \code{new("hexVP", ...)}.
+}
+\section{Slots}{
+ \describe{
+ \item{\code{hexVp.off}:}{Object of class \code{"viewport"} with
+ clipping set to off, see \code{\link[grid]{viewport}}.}
+ \item{\code{hexVp.on}:}{Object of class \code{"viewport"}, with the same
+ dimensions and parameters as hexVp.off, but with
+ clipping set to on, see \code{\link[grid]{viewport}}.}
+ \item{\code{hp.name}:}{The name of the viewport for searching a vptree}.
+ \item{\code{mar}:}{\code{\link[grid]{unit}} vector of four margins
+ (typically in \code{"lines"}).}
+ \item{\code{fig}:}{\code{\link[grid]{unit}} vector of two figure sizes
+ (typically in \code{"npc"}).}
+ \item{\code{plt}:}{\code{\link[grid]{unit}} vector of two figure sizes
+ (typically in \code{"npc"}).}
+ %% MM {FIXME?}: Is n't this simply ``xlim'' - then call it so!
+ %% NL, yes it is, but xscale and yscale is the parameters used by
+ %% grid.
+ \item{\code{shape}:}{The shape parameter from the plotted
+ \code{\link[hexbin]{hexbin}} object.}
+ \item{\code{xscale}:}{numeric of length two specifying x-range.}
+ \item{\code{yscale}:}{numeric of length two specifying y-range.}
+ }
+}
+\section{Methods}{
+ These are methods accessing the slots of corresponding name.
+ \describe{
+ \item{getFig}{\code{signature(hvp = "hexVP")}: ... }
+ \item{getMargins}{\code{signature(hvp = "hexVP")}: ... }
+ \item{getPlt}{\code{signature(hvp = "hexVP")}: ... }
+ \item{getXscale}{\code{signature(hvp = "hexVP")}: ... }
+ \item{getYscale}{\code{signature(hvp = "hexVP")}: ... }
+ }
+}
+\author{
+ Nicholas Lewin-Koh \email{kohnicho at comp.nus.edu.sg}.
+}
+\seealso{
+ The constructor function \code{\link{hexViewport}}.
+ \code{\link{hexbin}}, and its S4 plotting method,
+ \code{\link{gplot.hexbin}}.
+}
+\examples{
+ library("grid")
+ example(hexViewport, echo=FALSE)
+ ## continued:
+ str(P$plot.vp)
+}
+\keyword{classes}
diff --git a/man/hexVP.abline.Rd b/man/hexVP.abline.Rd
new file mode 100644
index 0000000..3d9abf2
--- /dev/null
+++ b/man/hexVP.abline.Rd
@@ -0,0 +1,44 @@
+\name{hexVP.abline}
+\alias{hexVP.abline}
+\title{Add a Straight Line to a HexPlot}
+\description{
+ This function adds one or more straight lines through the current
+ plot; it is the hexbin version of \code{\link[graphics]{abline}()}.
+}
+\usage{
+hexVP.abline(hvp, a = NULL, b = NULL, h = numeric(0), v = numeric(0),
+ col = "black", lty = 1, lwd = 2, \dots)
+}
+\arguments{
+ \item{hvp}{A hexViewport object that is currently on the active device}
+ \item{a,b}{the intercept and slope or if \code{b} is \code{NULL},
+ an \code{lm} object or a vector of length 2 with
+ \code{c(intercept,slope)}}
+ \item{h}{the y-value for a horizontal line.}
+ \item{v}{the x-value for a vertical line.}
+ \item{col, lty, lwd}{line color, type and width.}
+ \item{\dots}{further graphical parameters.}
+}
+\details{
+ The first form specifies the line in intercept/slope form
+ (alternatively \code{a} can be specified on its own and is taken to
+ contain the slope and intercept in vector form).
+
+ The \code{h=} and \code{v=} forms draw horizontal and vertical
+ lines at the specified coordinates.
+
+ The \code{coef} form specifies the line by a vector containing the
+ slope and intercept.
+
+ \code{lm} is a regression object which contains \code{reg$coef}. If it is
+ of length 1 then the value is taken to be the slope of a line
+ through the origin, otherwise, the first 2 values are taken to be
+ the intercept and slope.
+}
+\author{Nicholas Lewin-Koh}
+
+\seealso{\code{\link{gplot.hexbin}}, \code{\link{hexViewport}},
+ \code{\link{hexMA.loess}}
+}
+\keyword{aplot}
+
diff --git a/man/hexViewport.Rd b/man/hexViewport.Rd
new file mode 100644
index 0000000..ccb5b8d
--- /dev/null
+++ b/man/hexViewport.Rd
@@ -0,0 +1,55 @@
+\name{hexViewport}
+\alias{hexViewport}
+\title{Compute a Grid Viewport for Hexagon / Hexbin Graphics}
+\description{
+ Builds a \code{grid} viewport for hexagon or \code{\link{hexbin}}
+ graphics. This builds on the concepts of the \pkg{grid} package,
+ see \code{\link[grid]{viewport}}.
+}
+\usage{% see ../R/hexViewport.R
+hexViewport(x, offset = unit(0,"inches"), mar = NULL,
+ xbnds = NULL, ybnds = NULL, newpage = FALSE,
+ clip = "off", vp.name = NULL)
+}
+\arguments{
+ \item{x}{a \code{\link{hexbin}} object.}
+ \item{offset}{a \code{\link[grid]{unit}} object.}
+ \item{mar}{margins as \code{\link[grid]{unit}}s, of length 4 or 1.}
+ \item{xbnds, ybnds}{bounds for x- and y- plotting range; these default
+ to the corresponding slots of \code{x}.}
+ \item{newpage}{logical indicating if a new graphics page should be
+ openend, i.e., \code{\link[grid]{grid.newpage}()}.}
+ \item{clip}{simply passed to \code{\link[grid]{viewport}()}.}
+ \item{vp.name}{name of viewport; defaults to random name.}
+}
+\value{
+ an S4 object of class \code{"hexVP"}, see \link{hexVP-class} for more,
+ with its main slot \code{hexVp} a \code{\link[grid]{viewport}} for
+ grid graphics.
+}
+
+\seealso{\code{\link[grid]{viewport}} and the main
+ \emph{\dQuote{handlers}} \code{\link{pushHexport}} and
+ \code{\link[grid:viewports]{popViewport}}; further
+ \code{\link{gplot.hexbin}} and \code{\link{hboxplot}} which build on
+ \code{hexViewport}.
+}
+\examples{
+set.seed(131)
+x <- rnorm(7777)
+y <- rt (7777, df=3)
+
+## lower resolution binning and overplotting with counts
+bin <- hexbin(x,y,xbins=25)
+P <- plot(bin)
+xy <- hcell2xy(bin)
+pushHexport(P$plot.vp)
+i <- bin at count <= 3
+library("grid")
+grid.text(as.character(bin at count[i]), xy$x[i], xy$y[i],
+ default.units = "native")
+grid.points(x[1:20],y[1:20]) # to show some points rather than counts
+popViewport()
+}
+\keyword{hplot}% ?
+\keyword{aplot}
diff --git a/man/hexbin.Rd b/man/hexbin.Rd
new file mode 100644
index 0000000..293abe6
--- /dev/null
+++ b/man/hexbin.Rd
@@ -0,0 +1,110 @@
+\name{hexbin}
+\title{Bivariate Binning into Hexagon Cells}
+\alias{hexbin}
+\alias{hexbin-class}
+\alias{integer or NULL-class}
+\alias{show,hexbin-method}
+\alias{summary,hexbin-method}
+\description{
+ Creates a \code{"hexbin"} object. Basic components are a cell id and
+ a count of points falling in each occupied cell.
+
+ Basic methods are \code{\link[methods]{show}()}, \code{plot()} %(\link{plot.hexbin})
+ and \code{\link{summary}()}, but also \code{\link{erode}}.
+ % .. \code{\link{smooth.hexbin}}
+}
+\usage{
+hexbin(x, y, xbins = 30, shape = 1,
+ xbnds = range(x), ybnds = range(y),
+ xlab = NULL, ylab = NULL, IDs = FALSE)
+}
+\arguments{
+ \item{x, y}{vectors giving the coordinates of the bivariate data
+ points to be binned. Alternatively a single plotting structure can
+ be specified: see \code{\link[grDevices]{xy.coords}}. \code{\link{NA}}'s are
+ allowed and silently omitted.}
+ \item{xbins}{the number of bins partitioning the range of xbnds.}
+ \item{shape}{the \emph{shape} = yheight/xwidth of the plotting regions.}
+ \item{xbnds, ybnds}{horizontal and vertical limits of the binning
+ region in x or y units respectively; must be numeric vector of length 2.}
+ \item{xlab, ylab}{optional character strings used as labels for
+ \code{x} and \code{y}. If \code{NULL}, sensible defaults are used.}
+ \item{IDs}{logical indicating if the individual cell \dQuote{IDs}
+ should be returned, see also below.}
+}
+\value{
+ an S4 object of class \code{"hexbin"}.
+ It has the following slots:
+ \item{cell}{vector of cell ids that can be mapped into the (x,y)
+ bin centers in data units.}
+ \item{count}{vector of counts in the cells.}
+ \item{xcm}{The x center of mass (average of x values) for the cell.}
+ \item{ycm}{The y center of mass (average of y values) for the cell.}
+ \item{xbins}{ number of hexagons across the x axis. hexagon inner
+ diameter =diff(xbnds)/xbins in x units}
+ \item{shape}{plot shape which is yheight(inches) / xwidth(inches)}
+ \item{xbnds}{x coordinate bounds for binning and plotting}
+ \item{ybnds}{y coordinate bounds for binning and plotting}
+ \item{dimen}{The i and j limits of cnt treated as a matrix cnt[i,j]}
+ \item{n}{number of (non NA) (x,y) points, i.e., \code{sum(* @count)}.}
+ \item{ncells}{number of cells, i.e., \code{length(* @count)}, etc}
+ \item{call}{the function call.}
+ \item{xlab, ylab}{character strings to be used as axis labels.}
+ \item{cID}{of class, \code{"integer or NULL"}, only if \code{IDs}
+ was true, an integer vector of length \code{n} where
+ \code{cID[i]} is the cell number of the i-th original point
+ \code{(x[i], y[i])}. Consequently, the \code{cell} and \code{count}
+ slots are the same as the \code{\link{names}} and entries of
+ \code{table(cID)}, see the example.}
+}
+
+\seealso{
+ \code{\link{hcell2xy}}%, \code{\link{hcell}},
+% FIXME
+ \code{\link{gplot.hexbin}},% \code{\link{hboxplot}},
+% \code{\link{hdiffplot}}, \code{\link{hmatplot}},
+ \code{\link{grid.hexagons}}, \code{\link{grid.hexlegend}}.
+}
+
+\references{
+ Carr, D. B. et al. (1987)
+ Scatterplot Matrix Techniques for Large \eqn{N}.
+ \emph{JASA} \bold{83}, 398, 424--436.
+}
+
+\details{
+ Returns counts for non-empty cells only. The plot shape must be maintained for
+ hexagons to appear with equal sides. Some calculations are in single
+ precision.
+
+ Note that when plotting a \code{hexbin} object, the
+ \pkg{grid} package is used.
+ You must use its graphics (or those from package \pkg{lattice} if you
+ know how) to add to such plots.
+}
+
+\examples{
+set.seed(101)
+x <- rnorm(10000)
+y <- rnorm(10000)
+(bin <- hexbin(x, y))
+## or
+plot(hexbin(x, y + x*(x+1)/4),
+ main = "(X, X(X+1)/4 + Y) where X,Y ~ rnorm(10000)")
+
+## Using plot method for hexbin objects:
+plot(bin, style = "nested.lattice")
+
+hbi <- hexbin(y ~ x, xbins = 80, IDs= TRUE)
+str(hbi)
+tI <- table(hbi at cID)
+stopifnot(names(tI) == hbi at cell,
+ tI == hbi at count)
+
+## NA's now work too:
+x[runif(6, 0, length(x))] <- NA
+y[runif(7, 0, length(y))] <- NA
+hbN <- hexbin(x,y)
+summary(hbN)
+}
+\keyword{dplot}
diff --git a/man/hexbinplot.Rd b/man/hexbinplot.Rd
new file mode 100644
index 0000000..0233a76
--- /dev/null
+++ b/man/hexbinplot.Rd
@@ -0,0 +1,222 @@
+\name{hexbinplot}
+\alias{hexbinplot}
+\alias{hexbinplot.formula}
+\alias{panel.hexbinplot}
+\alias{prepanel.hexbinplot}
+\alias{hexlegendGrob}
+\title{Trellis Hexbin Displays}
+\description{
+
+ Display of hexagonally binned data, as implemented in the
+ \code{hexbin} packge, under the Trellis framework, with associated
+ utilities. \code{hexbinplot} is the high level generic function, with
+ the \code{"formula"} method doing the actual work.
+ \code{prepanel.hexbinplot} and \code{panel.hexbinplot} are associated
+ prepanel and panel functions. \code{hexlegendGrob} produces a
+ suitable legend.
+
+}
+\usage{
+
+hexbinplot(x, data, \dots)
+
+\method{hexbinplot}{formula}(x, data = NULL,
+ prepanel = prepanel.hexbinplot,
+ panel = panel.hexbinplot,
+ groups = NULL,
+ aspect = "xy",
+ trans = NULL,
+ inv = NULL,
+ colorkey = TRUE,
+ \dots,
+ maxcnt,
+ legend = NULL,
+ legend.width = TRUE,
+ subset)
+
+prepanel.hexbinplot(x, y, type = character(0), \dots)
+
+panel.hexbinplot(x, y, ..., groups = NULL)
+
+hexlegendGrob(legend = 1.2,
+ inner = legend / 5,
+ cex.labels = 1,
+ cex.title = 1.2,
+ style = "colorscale",
+ minarea = 0.05, maxarea = 0.8,
+ mincnt = 1, maxcnt,
+ trans = NULL, inv = NULL,
+ colorcut = seq(0, 1, length = 17),
+ density = NULL, border = NULL, pen = NULL,
+ colramp = function(n) { LinGray(n,beg = 90,end = 15) },
+ \dots,
+ vp = NULL,
+ draw = FALSE)
+
+
+}
+\arguments{
+ \item{x}{ For \code{hexbinplot}, the object on which method dispatch
+ is carried out.
+
+ For the \code{"formula"} methods, a formula describing the form of
+ conditioning plot. Formulas that are valid for \code{xyplot} are
+ acceptable.
+
+ In \code{panel.hexbinplot}, the x variable.
+ }
+ \item{y}{ In \code{panel.hexbinplot}, the y variable. }
+
+ \item{data}{For the \code{formula} method, a data frame containing
+ values for any variables in the formula, as well as \code{groups}
+ and \code{subset} if applicable (using \code{groups} currently
+ causes an error with the default panel function). By default, the
+ environment where the function was called from is used. }
+
+ \item{minarea, maxarea, mincnt, maxcnt, trans, inv, colorcut, density,
+ border, pen, colramp, style}{ see
+ \code{\link[hexbin:gplot.hexbin]{gplot.hexbin}} }
+
+ \item{prepanel, panel, aspect}{ See
+ \code{\link[lattice]{xyplot}}. \code{aspect="fill"} is not
+ allowed. The current default of \code{"xy"} may not always be the
+ best choice, often \code{aspect=1} will be more reasonable. }
+
+ \item{colorkey}{logical, whether a legend should be drawn. Currently
+ a legend can be drawn only on the right. }
+
+ \item{legend.width, legend}{ width of the legend in inches when
+ \code{style} is \code{"nested.lattice"} or
+ \code{"nested.centroids"}. The name \code{legend.width} is used to
+ avoid conflict with the standard trellis argument \code{legend}. It
+ is possible to specify additional legends using the \code{legend} or
+ \code{key} arguments as long as they do not conflict with the
+ hexbin legend (i.e., are not on the right). }
+
+ \item{inner}{ Inner radius in inches of hexagons in the legend when
+ \code{style} is \code{"nested.lattice"} or
+ \code{"nested.centroids"}. }
+
+ \item{cex.labels, cex.title}{ in the legend, multiplier for numeric
+ labels and text annotation respectively }
+
+ \item{type}{ character vector controlling additional augmentation of
+ the display. A \code{"g"} in \code{type} adds a reference grid,
+ \code{"r"} adds a regression line (y on x), \code{"smooth"} adds a
+ loess smooth }
+ \item{draw}{ logical, whether to draw the legend grob. Useful when
+ \code{hexlegendGrob} is used separately }
+ \item{vp}{ grid viewport to draw the legend in }
+
+ \item{\dots}{ extra arguments, passed on as appropriate. Arguments to
+ \code{\link[hexbin:gplot.hexbin]{gplot.hexbin}},
+ \code{\link[lattice]{xyplot}}, \code{panel.hexbinplot} and
+ \code{hexlegendGrob} can be supplied to the high level
+ \code{hexbinplot} call.
+
+ \code{panel.hexbinplot} calls one of two (unexported) low-level
+ functions depending on whether \code{groups} is supplied (although
+ specifying \code{groups} currently leads to an error). Arguments of
+ the appropriate function can be supplied; some important ones are
+
+ \describe{
+
+ \item{\code{xbins}:}{ number of hexagons covering x values. The
+ number of y-bins depends on this, the aspect ratio, and
+ \code{xbnds} and \code{ybnds}}
+
+ \item{\code{xbnds, ybnds}:}{ Numeric vector specifying range of
+ values that should be covered by the binning. In a multi-panel
+ display, it is not necessarily a good idea to use the same
+ bounds (which along with \code{xbins} and the aspect ratio
+ determine the size of the hexagons) for all panels. For
+ example, when data is concentrated in small subregions of
+ different panels, more detail will be shown by using smaller
+ hexagons covering those regions. To control this, \code{xbnds}
+ and \code{ybnds} can also be character strings \code{"panel"} or
+ \code{"data"} (which are not very good names and may be changed
+ in future). In the first case, the bounds are taken to be the
+ limits of the panel, in the second case, the limits of the data
+ (packet) in that panel. Note that all panels will have the same
+ limits (enough to cover all the data) by default if
+ \code{relation="free"} in the standard trellis argument
+ \code{scales}, but not otherwise.}
+
+ }
+
+ }
+
+ \item{groups}{ in \code{hexbinplot}, a grouping variable that is
+ evaluated in \code{data}, and passed on to the panel function. }
+
+ \item{subset}{ an expression that is evaluated in evaluated in
+ \code{data} to produce a logical vector that is used to subset the
+ data before being used in the plot. }
+
+}
+\details{
+
+ The panel function \code{panel.hexbinplot} creates a hexbin object
+ from data supplied to it and plots it using
+ \code{\link[hexbin:grid.hexagons]{grid.hexagons}}. To make panels
+ comparable, all panels have the same \code{maxcnt} value, by default
+ the maximum count over all panels. This default value can be
+ calculated only if the aspect ratio is known, and so
+ \code{aspect="fill"} is not allowed. The default choice of aspect
+ ratio is different from the choice in \code{hexbin} (namely,
+ \code{1}), which may sometimes give better results for multi-panel
+ displays. \code{xbnds} and \code{ybnds} can be numeric range vectors
+ as in \code{hexbin}, but they can also be character strings specifying
+ whether all panels should have the same bins. If they are not, then
+ bins in different panels could be of different sizes, in which case
+ \code{style="lattice"} and \code{style="centroids"} should be
+ interpreted carefully.
+
+
+ The dimensions of the legend and the size of the hexagons therein are
+ given in absolute units (inches) by \code{legend.width} and
+ \code{inner} only when \code{style} is \code{"nested.lattice"} or
+ \code{"nested.centroids"}. For other styles, the dimensions of the
+ legend are determined relative to the plot. Specifically, the height
+ of the legend is the same as the height of the plot (the panel and
+ strip regions combined), and the width is the minimum required to fit
+ the legend in the display. This is different in some ways from the
+ \code{hexbin} implementation. In particular, the size of the hexagons
+ in the legend are completely unrelated to the sizes in the panels,
+ which is pretty much unavoidable because the sizes need not be the
+ same across panels if \code{xbnds} or \code{ybnds} is \code{"data"}.
+ The size of the hexagons encode information when \code{style} is
+ \code{"lattice"} or \code{"centroids"}, consequently a warning is
+ issued when a legend is drawn with wither of these styles.
+
+}
+
+\value{
+ \code{hexbinplot} produces an object of class \code{"trellis"}. The
+ \code{update} method can be used to update components of the object and
+ the \code{print} method (usually called by default) will plot it on an
+ appropriate plotting device. \code{hexlegendGrob} produces a
+ \code{"grob"} (grid object).
+
+}
+\author{ Deepayan Sarkar \email{deepayan at stat.wisc.edu}}
+\seealso{
+ \code{\link{hexbin}}, \code{\link[lattice]{xyplot}}
+}
+
+\examples{
+mixdata <-
+ data.frame(x = c(rnorm(5000),rnorm(5000,4,1.5)),
+ y = c(rnorm(5000),rnorm(5000,2,3)),
+ a = gl(2, 5000))
+hexbinplot(y ~ x, mixdata, aspect = 1,
+ trans = sqrt, inv = function(x) x^2)
+hexbinplot(y ~ x | a, mixdata)
+hexbinplot(y ~ x | a, mixdata, style = "lattice",
+ xbnds = "data", ybnds = "data")
+hexbinplot(y ~ x | a, mixdata, style = "nested.centroids")
+hexbinplot(y ~ x | a, mixdata, style = "nested.centroids",
+ border = FALSE, type = c("g", "smooth"))
+}
+
+\keyword{dplot}
diff --git a/man/hexplom.Rd b/man/hexplom.Rd
new file mode 100644
index 0000000..8365b1b
--- /dev/null
+++ b/man/hexplom.Rd
@@ -0,0 +1,96 @@
+\name{hexplom}
+\title{Hexbin Plot Matrices}
+\alias{hexplom}
+\alias{hexplom.formula}
+\alias{hexplom.data.frame}
+\alias{hexplom.matrix}
+\alias{panel.hexplom}
+
+\usage{
+hexplom(x, data, \dots)
+
+\method{hexplom}{formula}(x, data = NULL, \dots)
+
+\method{hexplom}{data.frame}(x, data = NULL, \dots, groups = NULL,
+ subset = TRUE)
+
+\method{hexplom}{matrix}(x, data = NULL, \dots, groups = NULL, subset = TRUE)
+
+panel.hexplom(\dots)
+}
+
+\description{
+ \code{hexplom} draws Conditional Hexbin Plot Matrices. It is similar
+ to \code{splom}, expect that the default display is different.
+ Specifically, the default display is created using
+ \code{panel.hexplom}, which is an alias for \code{panel.hexbinplot}.
+}
+
+\arguments{
+ \item{x}{
+ The object on which method dispatch is carried out.
+
+ For the \code{"formula"} method, a formula describing the structure
+ of the plot, which should be of the form \code{~ x | g1 * g2 *
+ \dots}, where \code{x} is a data frame or matrix. Each of \code{g1,
+ g2, \dots} must be either factors or shingles. The conditioning
+ variables \code{g1, g2, \dots} may be omitted.
+
+ For the \code{data.frame} and \code{matrix} methods, a data frame or
+ matrix as appropriate.
+ }
+ \item{data}{
+ For the \code{formula} method, an optional data frame in which
+ variables in the formula (as well as \code{groups} and
+ \code{subset}, if any) are to be evaluated. By default, the
+ environment where the function was called from is used.
+ }
+
+ \item{groups, subset, \dots}{ see \code{\link[lattice]{splom}}. The
+ non-standard evaluation of \code{groups} and \code{subset} only
+ applies in the \code{formula} method. Apart from arguments that
+ apply to \code{splom} (many of which are only documented in
+ \code{\link[lattice]{xyplot}}), additional arguments meant for
+ \code{panel.hexplom} (which is an alias for
+ \code{\link{panel.hexbinplot}}) may also be supplied. Such
+ arguments may include ones that control details of the hexbin
+ calculations, documented in \code{\link{gplot.hexbin}}}
+
+}
+\value{
+
+ An object of class \code{"trellis"}. The
+ \code{\link[lattice:update.trellis]{update}} method can be used to
+ update components of the object and the
+ \code{\link[lattice:print.trellis]{print}} method (usually called by
+ default) will plot it on an appropriate plotting device.
+
+}
+
+\seealso{
+ \code{\link[lattice]{splom}}, \code{\link[lattice]{xyplot}},
+ \code{\link[hexbin]{hexbinplot}},
+ \code{\link[lattice]{Lattice}}, \code{\link[lattice]{panel.pairs}}
+}
+
+\author{ Deepayan Sarkar \email{Deepayan.Sarkar at R-project.org},
+ Nicholas Lewin-Koh \email{nikko at hailmail.net}}
+
+\examples{
+
+## Simple hexplom
+data(NHANES)
+hexplom(~NHANES[,7:14], xbins=15)
+
+## With colors and conditioning
+hexplom(~NHANES[,9:13] | Sex, data = NHANES,
+ xbins = 15, colramp = magent)
+
+## With custom panel function
+hexplom(NHANES[,9:13], xbins = 20,colramp = BTY,
+ upper.panel = panel.hexboxplot)
+
+
+}
+\keyword{hplot}
+
diff --git a/man/hexpolygon.Rd b/man/hexpolygon.Rd
new file mode 100644
index 0000000..cfa38d0
--- /dev/null
+++ b/man/hexpolygon.Rd
@@ -0,0 +1,78 @@
+\name{hexpolygon}
+\alias{hexpolygon}
+\alias{hexcoords}
+\title{Hexagon Coordinates and Polygon Drawing}
+\description{
+ Simple \sQuote{low-level} function for computing and drawing hexagons.
+ Can be used for \sQuote{grid} (package \pkg{grid}) or
+ \sQuote{traditional} (package \pkg{graphics}) graphics.
+}
+\usage{
+hexcoords(dx, dy = NULL, n = 1, sep = NULL)
+
+hexpolygon(x, y, hexC = hexcoords(dx, dy, n = 1), dx, dy = NULL,
+ fill = 1, border = 0, hUnit = "native", ...)
+}
+\arguments{
+ \item{dx,dy}{horizontal and vertical width of the hexagon(s).}
+ \item{n}{number of hexagon \dQuote{repeats}.}
+ \item{sep}{separator value to be put between coordinates of different
+ hexagons. The default, \code{NULL} doesn't use a separator.}
+ \item{x,y}{numeric vectors of the same length specifying the hexagon
+ \emph{centers} around which to draw.}
+ \item{hexC}{a list as returned from \code{hexcoords()}.
+ Its component \code{no.sep} determines if grid or traditional
+ graphics are used. The default (via default of \code{hexcoords}) is
+ now to use grid graphics.}
+ \item{fill,border}{passed to \code{\link[grid]{grid.polygon}} (for \pkg{grid}).}
+ \item{hUnit}{string or \code{NULL} determining in which units (x,y)
+ values are.}
+ \item{\dots}{further arguments passed to \code{\link{polygon}} (for
+ \pkg{graphics}).}
+}
+\value{
+ \code{hexcoords()} returns a list with components
+ \item{x,y}{numeric vectors of length \eqn{n \times 6}{n * 6} (or
+ \eqn{n \times 7}{n * 7} if \code{sep} is not NULL)
+ specifying the hexagon polygon coordinates (with \code{sep} appended
+ to each 6-tuple).}
+ \item{no.sep}{a logical indicating if \code{sep} was \code{NULL}.}
+
+ \code{hexpolygon} returns what its last \code{\link[grid]{grid.polygon}(.)}
+ or \code{\link{polygon}(.)} call returns.
+}
+\author{Martin Maechler, originally.}
+\seealso{\code{\link{grid.hexagons}} which builds on these.}
+\examples{
+str(hexcoords(1, sep = NA)) # multiple of (6 + 1)
+str(hexcoords(1, sep = NULL))# no separator -> multiple of 6
+\dontshow{
+stopifnot(3 * (6+1) == sapply(hexcoords(2, n = 3, sep = NA)[1:2], length),
+ 6 == sapply(hexcoords(1)[1:2], length))
+set.seed(1001)
+}
+
+## hexpolygon()s:
+x <- runif(20, -2, 2)
+y <- x + rnorm(20)
+
+## 1) traditional 'graphics'
+plot(x,y, asp = 1, "plot() + hexpolygon()")
+hexpolygon(x,y, dx = 0.1, density = 25, col = 2, lwd = 1.5)
+
+## 2) "grid" :
+
+addBit <- function(bnds, f = 0.05) bnds + c(-f, f) * diff(bnds)
+sc <- addBit(rxy <- range(x,y))# same extents (cheating asp=1)
+library("grid")
+grid.newpage()
+pushViewport(plotViewport(.1+c(4,4,2,1), xscale = sc, yscale = sc))
+grid.rect()
+grid.xaxis()
+grid.yaxis()
+grid.points(x,y)
+hexpolygon(x,y, hexcoords(dx = 0.1, sep=NULL), border = "blue", fill=NA)
+popViewport()
+}
+\keyword{dplot}
+\keyword{aplot}
diff --git a/man/hsmooth-methods.Rd b/man/hsmooth-methods.Rd
new file mode 100644
index 0000000..ee8185a
--- /dev/null
+++ b/man/hsmooth-methods.Rd
@@ -0,0 +1,28 @@
+\name{hsmooth-methods}
+\docType{methods}% + generic -- still use this doctype ?
+\alias{hsmooth}% generic
+\alias{hsmooth-methods}
+\alias{hsmooth,hexbin-method}
+\title{Hexagon Bin Smoothing: Generic hsmooth() and Methods}
+\description{
+ Methods for the generic function \code{hsmooth} in package
+ \pkg{hexbin}:
+ There is currently only the one for \code{\link{hexbin}} objects.
+}
+\usage{
+\S4method{hsmooth}{hexbin}(bin, wts)
+}
+\arguments{
+ \item{bin}{a \code{\link{hexbin}} object, or an extension such as
+ \code{\link{erodebin-class}}.}
+ \item{wts}{weights vector, see \code{\link{smooth.hexbin}}}
+}
+\section{Methods}{
+ \describe{
+ \item{bin = "hexbin"}{is just the \code{\link{smooth.hexbin}}
+ function (for back compatibility); see its documentation, also for
+ examples.}
+ }
+}
+\keyword{methods}
+
diff --git a/man/inout.hex.Rd b/man/inout.hex.Rd
new file mode 100644
index 0000000..307e051
--- /dev/null
+++ b/man/inout.hex.Rd
@@ -0,0 +1,31 @@
+\name{inout.hex}
+\alias{inout.hex}
+\title{Check points for inclusion}
+\description{
+ Check which points are in hexagons with \code{count} <= mincnt.
+}
+\usage{
+inout.hex(hbin, mincnt)
+}
+
+\arguments{
+ \item{hbin}{an object of class \code{\link{hexbin}}.}
+ \item{mincnt}{Cutoff, id's for counts less than mincnt are returned}
+}
+\details{
+ Check which points are in hexagons with \code{count} <= mincnt and
+ returns the row ids for those points. One can use the ids to plot low
+ ount hexagons as points instead.
+}
+\value{
+ A vector with the row ids of points which fall in hexagons with
+ \code{count} less than or equal to mincnt
+}
+
+\author{Nicholas Lewin-Koh}
+
+
+\seealso{\code{\link{plotMAhex}}}
+
+\keyword{misc}
+
diff --git a/man/list2hexList.Rd b/man/list2hexList.Rd
new file mode 100644
index 0000000..ab40823
--- /dev/null
+++ b/man/list2hexList.Rd
@@ -0,0 +1,25 @@
+\name{list2hexList}
+\alias{list2hexList}
+\title{Convert list to hexList}
+\description{
+ Converts a list of hexbin objects with same xbnds, ybnds, shape and
+ xbins to a \code{\link{hexList}} object.
+}
+\usage{
+list2hexList(binlst)
+}
+\arguments{
+ \item{binlst}{A list of hexbin objects}
+}
+
+\value{
+ a \code{\link{hexList}} object
+}
+
+\author{Nicholas Lewin-Koh}
+
+
+\seealso{\code{\link{hexList}},\code{\link{hdiffplot}} }
+
+\keyword{misc}
+
diff --git a/man/old-classes.Rd b/man/old-classes.Rd
new file mode 100644
index 0000000..efec494
--- /dev/null
+++ b/man/old-classes.Rd
@@ -0,0 +1,24 @@
+\name{old-classes}
+\title{Class "unit" and "viewport" as S4 classes}
+%
+\docType{class}
+\alias{unit-class}
+\alias{viewport-class}
+%
+\description{Package "hexbin" now uses S4 classes throughout and hence
+ needs to \code{\link[methods]{setOldClass}} both \code{"unit"} and
+ \code{"viewport"} (which are S3 classes from the \pkg{grid} package),
+ in order to be able to use those in slots of its own classes.
+}
+\section{Objects from the Class}{A virtual Class: No objects may be
+ created from it.}
+\section{Extends}{
+ Class \code{"oldClass"}, directly.
+}
+\section{Methods}{
+ No methods defined with class "unit" in the signature.
+}
+% \seealso{
+% add link to grid ??
+% }
+\keyword{classes}
diff --git a/man/optShape.Rd b/man/optShape.Rd
new file mode 100644
index 0000000..6ed8c10
--- /dev/null
+++ b/man/optShape.Rd
@@ -0,0 +1,50 @@
+\name{optShape}
+\alias{optShape}
+%- Also NEED an '\alias' for EACH other topic documented here.
+\title{Optimal Shape Parameter for Hexbin Viewport}
+\description{
+ Takes a viewport or a given height and width and returns the shape
+ parameter that will fill the specified plotting region with the
+ appropriately shaped hexagons. If margins are specified the margins
+ are subtracted from height and width before the shape parameter is
+ specified.
+}
+\usage{
+optShape(vp, height = NULL, width = NULL, mar = NULL)
+}
+\arguments{
+ \item{vp}{a \code{viewport} object, optional see details}
+ \item{height}{the height of the plotting region, can be numeric or units}
+ \item{width}{The width of the plotting region, can be numeric or units}
+ \item{mar}{A four element numeric or units vector describing the
+ margins in the order \code{c(bottom, left, top, right)}}
+}
+\value{
+ a scalar numeric value specifiyng \code{shape}.
+}
+\author{Nicholas Lewin-Koh}
+\section{Warning}{If a viewport is given as an argument it should
+ already be pushed on the graphics device or it will have null units
+ and a meaningless shape parameter will be returned.
+}
+\seealso{\code{\link{hexViewport}}, \code{\link{hexVP-class}},
+ \code{\link{hexbin}}}
+\examples{
+x <- rgamma(10000,.9)
+m <- as.logical(rbinom(10000,1,.17))
+x[m] <- -x[m]
+y <- rnorm(x,abs(x))
+library("grid")
+vp <- plotViewport(xscale= range(x)+c(-.5,.5),
+ yscale= range(y)+c(-.5,.5),
+ default.units = "native")
+grid.newpage()
+pushViewport(vp)
+grid.rect()
+shape <- optShape(vp)
+shape
+hb <- hexbin(x,y,xbins=40,shape=shape)
+grid.hexagons(hb,colramp=BTY)
+}
+\keyword{dplot}
+
diff --git a/man/panel.hexboxplot.Rd b/man/panel.hexboxplot.Rd
new file mode 100644
index 0000000..305a8bb
--- /dev/null
+++ b/man/panel.hexboxplot.Rd
@@ -0,0 +1,49 @@
+\name{panel.hexboxplot}
+\alias{panel.hexboxplot}
+\title{Boxplot for hexbin lattice plot}
+\description{
+A panel function to add a boxplot to a hexbin lattice plot.
+}
+\usage{
+panel.hexboxplot(x, y, xbins = 30,
+ xbnds = c("data", "panel"), ybnds = c("data", "panel"),
+ .prelim = FALSE, .cpl = current.panel.limits(),
+ .xlim = .cpl$xlim, .ylim = .cpl$ylim,
+ .aspect.ratio, type = character(0), cdfcut = 0.25,
+ shadow = 0.05, ..., check.erosion = TRUE)
+}
+\arguments{
+ \item{x, y}{numeric vector or factor.}
+ \item{xbins}{the number of bins partitioning the range of xbnds.}
+ \item{xbnds, ybnds}{horizontal and vertical limits of the binning
+ region in x or y units respectively; must be numeric vector of
+ length 2.}
+ \item{.prelim, .cpl, .xlim, .ylim, .aspect.ratio}{for internal use.}
+ \item{type}{character vector controlling additional augmentation of
+ the display. A \code{"g"} in \code{type} adds a reference grid, an
+ \code{"hg"} adds a hexagonal grid.}
+ \item{cdfcut}{number in (0,1) indicating the confidence level for the
+ erosion limits. See \code{\link{erode.hexbin}} for more information.}
+ \item{shadow}{number in (0,1) indicating the confidence level for the
+ erosion limits of a boxplot shadow. See \code{\link{erode.hexbin}}
+ for more information.}
+ \item{\dots}{potential further arguments passed on.}
+ \item{check.erosion}{logical indicating only eroded points should be
+ used for \code{"erodebin"} objects; simply passed to
+ \code{\link{hcell2xy}}, see its documentation.}
+}
+\value{
+ There is no return value from this function. The results are plotted on
+ the current active device.
+}
+\author{Nicholas Lewin-Koh \email{nikko at hailmail.net}}
+\seealso{\code{\link{hexbinplot}}, \code{\link{panel.hexgrid}},
+ \code{\link[lattice]{panel.bwplot}}
+}
+\examples{
+mixdata <-
+ data.frame(x = c(rnorm(5000),rnorm(5000,4,1.5)),
+ y = rep(1:2, 5000))
+hexbinplot(y ~ x, mixdata, panel = panel.hexboxplot)
+}
+\keyword{hplot}
diff --git a/man/panel.hexgrid.Rd b/man/panel.hexgrid.Rd
new file mode 100644
index 0000000..341eb33
--- /dev/null
+++ b/man/panel.hexgrid.Rd
@@ -0,0 +1,21 @@
+\name{panel.hexgrid}
+\alias{panel.hexgrid}
+\title{Hexagonal grid for a lattice plot}
+\description{
+A panel function to add a hexagonal grid to a lattice plot.
+}
+\usage{
+panel.hexgrid(h, border = grey(0.85))
+}
+
+\arguments{
+ \item{h}{an object of class \code{hexbin}.}
+ \item{border}{a color for the hexagon border colors}
+}
+\value{
+ There is no return value from this function. The results are plotted on
+ the current active device.
+}
+\author{Nicholas Lewin-Koh \email{nikko at hailmail.net}}
+\seealso{\code{\link{hexbinplot}}, \code{\link{hexGraphPaper}}}
+\keyword{hplot}
diff --git a/man/panel.hexloess.Rd b/man/panel.hexloess.Rd
new file mode 100644
index 0000000..e96e985
--- /dev/null
+++ b/man/panel.hexloess.Rd
@@ -0,0 +1,41 @@
+\name{panel.hexloess}
+\alias{panel.hexloess}
+\title{Loess line for hexbin lattice plot}
+\description{
+ A panel function to add a loess line to a hexbin lattice plot.
+
+ This function contravened CRAN policy and is no longer available.
+}
+\usage{
+panel.hexloess(bin, w = NULL, span = 2/3, degree = 1,
+ family = c("symmetric", "gaussian"), evaluation = 50,
+ lwd = add.line$lwd, lty = add.line$lty,
+ col, col.line = add.line$col, \dots)
+
+}
+\arguments{
+ \item{bin}{an object of class \code{hexbin}.}
+ \item{w}{optional counts for object \code{bin}.}
+ \item{span}{smoothness parameter for \code{loess}.}
+ \item{degree}{degree of local polynomial used.}
+ \item{family}{if \code{"gaussian"} fitting is by least-squares, and
+ if \code{"symmetric"} a re-descending M-estimator is used.}
+ \item{evaluation}{number of points at which to evaluate the smooth curve.}
+ \item{lwd}{line weight graphical parameter.}
+ \item{lty}{line type graphical parameter.}
+ \item{col}{same as \code{col.line}.}
+ \item{col.line}{line color graphical parameter.}
+ \item{\dots}{optional arguments to \code{\link[stats]{loess.control}}.}
+}
+\value{
+ There is no return value from this function. The results are plotted on
+ the current active device.
+}
+\author{Nicholas Lewin-Koh \email{nikko at hailmail.net}}
+\seealso{
+\code{\link{hexbinplot}}, \code{\link{panel.hexgrid}},
+\code{\link{loess.smooth}},
+\code{\link{loess.control}},
+\code{\link[lattice:panel.functions]{panel.loess}}
+}
+\keyword{hplot}
diff --git a/man/plotMAhex.Rd b/man/plotMAhex.Rd
new file mode 100644
index 0000000..6dd5c0b
--- /dev/null
+++ b/man/plotMAhex.Rd
@@ -0,0 +1,133 @@
+\name{plotMAhex}
+\alias{plotMAhex}
+\title{MA-plot using hexagon bins}
+\description{
+ Creates an MA-plot using hexagons with color/glyph coding for control spots.
+}
+\usage{
+plotMAhex(MA, array = 1, xlab = "A", ylab = "M",
+ main = colnames(MA)[array], xlim = NULL, ylim = NULL,
+ status = NULL, values, pch, col, cex, nbin = 40,
+ zero.weights = FALSE, style = "colorscale", legend = 1.2,
+ lcex = 1, minarea = 0.04, maxarea = 0.8, mincnt = 2,
+ maxcnt = NULL, trans = NULL, inv = NULL, colorcut = NULL,
+ border = NULL, density = NULL, pen = NULL,
+ colramp = function(n) { LinGray(n, beg = 90, end = 15) },
+ newpage = TRUE, type = c("p", "l", "n"),
+ xaxt = c("s", "n"), yaxt = c("s", "n"),
+ verbose = getOption("verbose"))
+}
+\arguments{
+ \item{MA}{an \code{RGList}, \code{MAList} or \code{MArrayLM} object,
+ or any list with components \code{M} containing log-ratios and
+ \code{A} containing average intensities. Alternatively a
+ \code{matrix}, \code{Affybatch} or \code{ExpressionSet} object.}
+ \item{array}{integer giving the array to be plotted. Corresponds to
+ columns of \code{M} and \code{A}.}
+ \item{xlab, ylab, main}{character strings giving label for x-axis,
+ y-axis or main tile of the plot.}
+ \item{xlim, ylim}{numeric vectors of length 2 giving limits for x-axis
+ (or y-axis respectively), defaulting to min and max of the data.}
+ \item{status}{character vector giving the control status of each spot
+ on the array, of same length as the number of rows of \code{MA$M}.
+ If omitted, all points are plotted in the default color, symbol and size.}
+ \item{values}{character vector giving values of \code{status} to be
+ highlighted on the plot. Defaults to unique values of \code{status}.
+ Ignored if there is no \code{status} vector.}
+ \item{pch}{vector or list of plotting characters. Default to integer code 16.
+ Ignored is there is no \code{status} vector.}
+ \item{col}{numeric or character vector of colors, of the same length
+ as \code{values}. Defaults to \code{1:length(values)}. Ignored if
+ there is no \code{status} vector.}
+ \item{cex}{numeric vector of plot symbol expansions, of the the same
+ length as \code{values}. Defaults to 0.2 for the most common status
+ value and 1 for the others. Ignored if there is no \code{status} vector.}
+ \item{nbin}{ Number of bins } %% << FIXME
+ \item{zero.weights}{logical, should spots with zero or negative
+ weights be plotted?}
+ \item{style}{string specifying the style of hexagon plot,
+ see \code{\link{grid.hexagons}} for the possibilities.}
+ \item{legend}{numeric width of the legend in inches of \code{FALSE}.
+ In the latter case, or when \code{0}, no legend is not produced.}
+ \item{lcex}{characters expansion size for the text in the legend.}
+ \item{minarea}{fraction of cell area for the lowest count.}
+ \item{maxarea}{fraction of the cell area for the largest count.}
+ \item{mincnt}{cells with fewer counts are ignored.}
+ \item{maxcnt}{cells with more counts are ignored.}
+ \item{trans}{\code{\link{function}} specifying a transformation for
+ the counts such as \code{sqrt}.}
+ \item{inv}{the inverse transformation of \code{trans}.}
+ \item{colorcut}{vector of values covering [0, 1] that determine
+ hexagon color class boundaries and hexagon legend size boundaries.
+ Alternatively, an integer (\code{<= maxcnt}) specifying the
+ \emph{number} of equispaced colorcut values in [0,1].}
+ \item{border, density, pen}{color for polygon borders and filling of
+ each hexagon drawn, passed to \code{\link{grid.hexagons}}.}
+ \item{colramp}{function accepting an integer \code{n} as an argument and
+ returning n colors.}
+ \item{newpage}{should a new page start?}
+ \item{type, xaxt, yaxt}{strings to be used (when set to \code{"n"}) for
+ suppressing the plotting of hexagon symbols, or the x- or y-axis,
+ respectively.}
+ \item{verbose}{logical indicating if some diagnostic output should happen.}
+}
+
+\details{
+ An MA-plot is a plot of log-intensity ratios (M-values) versus
+ log-intensity averages (A-values). If \code{MA} is an \code{RGList} or
+ \code{MAList} then this function produces an ordinary within-array
+ MA-plot. If \code{MA} is an \code{MArrayLM} object, then the plot is an
+ fitted model MA-plot in which the estimated coefficient is on the y-axis
+ and the average A-value is on the x-axis.
+
+ If \code{MA} is a \code{matrix} or \code{ExpressionSet} object, then this
+ function produces a between-array MA-plot. In this case the A-values in
+ the plot are the average log-intensities across the arrays and the
+ M-values are the deviations of the log-intensities for the specified
+ array from the average. If there are more than five arrays, then the
+ average is computed robustly using medians. With five or fewer arrays,
+ it is computed by means.
+
+ The \code{status} vector is intended to specify the control status of
+ each spot, for example "gene", "ratio control", "house keeping gene",
+ "buffer" and so on. The vector is usually computed using the function
+ \code{\link[limma]{controlStatus}} from package \pkg{limma} and a
+ spot-types file. However the function may be used to highlight any
+ subset of spots.
+
+ The arguments \code{values}, \code{pch}, \code{col} and \code{cex}
+ can be included as attributes to \code{status} instead of being
+ passed as arguments to \code{plotMA}.
+
+ See \code{\link[graphics]{points}} for possible values for \code{pch},
+ \code{col} and \code{cex}.
+}
+
+\value{
+ A plot is created on the current graphics device.
+ and a list with the following items is returned invisibly:
+ \item{plot.vp}{the \code{\link{hexViewport}} constructed and used.}
+ \item{legend.vp}{if a legend has been produced, its
+ \code{\link[grid]{viewport}}.}
+ \item{hbin}{a \code{hexbin} object built with A as the x coordinate
+ and M as the y coordinate.}
+}
+
+\references{See \url{http://www.statsci.org/micrarra/refs/maplots.html}}
+
+\author{Nicholas Lewin-Koh, adapted from code by Gordon Smyth}
+
+\seealso{\code{\link[limma:plotma]{plotMA}} from package \pkg{limma},
+ and \code{\link{gplot.hexbin}}.
+}
+
+\examples{
+ if(require(marray)){ %% for the data only --> data(swirl, package="marray")
+ data(swirl)
+ hb <- plotMAhex(swirl[,1],newpage=FALSE,
+ main = "M vs A plot with hexagons", legend=0)
+ hexVP.abline(hb$plot.vp,h=0,col=gray(.6))
+ hexMA.loess(hb)
+ }
+}
+\keyword{hplot}
diff --git a/man/pushHexport.Rd b/man/pushHexport.Rd
new file mode 100644
index 0000000..49f07f4
--- /dev/null
+++ b/man/pushHexport.Rd
@@ -0,0 +1,29 @@
+\name{pushHexport}
+\alias{pushHexport}
+\title{Push a Hexagon Viewport ("hexVP")}
+\description{
+ Push a Hexagon Viewport (\code{"hexVP"}, see \link{hexVP-class}) on to
+ the tree of (grid) viewports, calling
+ \code{\link[grid:viewports]{pushViewport}}.
+}
+\usage{
+pushHexport(hvp, clip = "off")
+}
+\arguments{
+ \item{hvp}{a hexagon viewport, i.e., an object of class
+ \code{"hexVP"}, see \link{hexVP-class}, typically produced by
+ \code{\link{hexViewport}(..)}.}
+ \item{clip}{which viewport to push, either 'on' or 'off' are the
+ allowed arguments, see details.}
+}
+\seealso{the underlying \code{\link[grid:viewports]{pushViewport}} from the
+ \pkg{grid} package.
+}
+\details{
+ A hexagon viewport (\code{"hexVP"}) object has slots for two replicate
+ viewports one with clipping turned on and one with clipping off. This
+ allows toggling the clipping option.
+}
+%\examples{
+%}
+\keyword{dplot}
diff --git a/man/smooth.hexbin.Rd b/man/smooth.hexbin.Rd
new file mode 100644
index 0000000..92adc21
--- /dev/null
+++ b/man/smooth.hexbin.Rd
@@ -0,0 +1,84 @@
+\name{smooth.hexbin}
+\alias{smooth.hexbin}
+\alias{smoothbin-class}
+\title{Hexagon Bin Smoothing}
+\description{
+ Given a \code{"hexbin"} (hexagon bin) object, compute a discrete
+ kernel smoother that covers seven cells, namely a center cell and its
+ six neighbors. With two iterations the kernel effectively covers
+ 1+6+12=19 cells.
+}
+\usage{
+smooth.hexbin(bin, wts=c(48,4,1))
+}
+\arguments{
+ \item{bin}{object of class \code{"hexbin"}, typically resulting from
+ \code{\link{hexbin}()} or \code{\link{erode,hexbin-method}}.}
+ \item{wts}{numeric vector of length 3 for relative weights of the
+ center, the six neighbor cells, and twelve second neighbors.}
+}
+\value{
+ an object of class \code{"smoothbin"}, extending class
+ \code{"hexbin"}, see \code{\link{hexbin}}.
+ The object includes the additional slot \code{wts}.
+}
+\references{see \code{\link{grid.hexagons}} and \code{\link{hexbin}}.}
+
+\details{
+ This discrete kernel smoother uses the center cell, immediate
+ neighbors and second neighbors to smooth the counts. The counts for
+ each resulting cell is a linear combination of previous cell counts
+ and weights. The weights are
+ \tabular{ll}{
+ 1 center cell, \tab weight = wts[1]\cr
+ 6 immediate neighbors\tab weight = wts[2]\cr
+ 12 second neighbors \tab weight =wts[3]\cr
+ }
+ If a cell, its immediate and second neighbors all have a value of
+ \code{max(cnt)}, the new maximum count would be
+ \code{max(cnt)*sum(wts)}. It is possible for the counts to overflow.
+
+ The domain for cells with positive counts increases. The hexbin
+ slots \code{xbins}, \code{xbnds}, \code{ybnds}, and \code{dimen} all
+ reflect this increase.
+ Note that usually \code{dimen[2] = xbins+1}.
+
+ The intent was to provide a fast, iterated, immediate neighbor smoother.
+ However, the current hexbin plotting routines only support shifting
+ even numbered rows to the right. Future work can
+
+ (1) add a shift indicator to hexbin objects that indicates left or
+ right shifting.\cr
+ (2) generalize plot.hexbin() and hexagons()\cr
+ (3) provide an iterated kernel.\cr
+
+ With \code{wts[3]=0}, the smoother only uses the immediate neighbors.
+ With a shift indicator the domain could increase by 2 rows (one bottom
+ and on top) and 2 columns (one left and one right). However the current
+ implementation increases the domain by 4 rows and 4 columns, thus
+ reducing plotting resolution.
+}
+
+\seealso{
+ \code{\link{hexbin}}, \code{\link{erode.hexbin}}, %MISSING \code{\link{hthin}},
+ \code{\link{hcell2xy}},% \code{\link{hcell}},
+ \code{\link{gplot.hexbin}}, \code{\link{hboxplot}},
+ %\code{\link{hdiffplot}}, \code{\link{hmatplot}},
+ \code{\link{grid.hexagons}}, \code{\link{grid.hexlegend}}.
+}
+\examples{
+x <- rnorm(10000)
+y <- rnorm(10000)
+bin <- hexbin(x,y)
+# show the smooth counts in gray level
+smbin <- smooth.hexbin(bin)
+plot(smbin, main = "smooth.hexbin(.)")
+
+# Compare the smooth and the origin
+smbin1 <- smbin
+smbin1 at count <- as.integer(ceiling(smbin at count/sum(smbin at wts)))
+plot(smbin1)
+smbin2 <- smooth.hexbin(bin,wts=c(1,0,0)) # expand the domain for comparability
+plot(smbin2)
+}
+\keyword{misc}
diff --git a/src/hbin.f b/src/hbin.f
new file mode 100644
index 0000000..00737b3
--- /dev/null
+++ b/src/hbin.f
@@ -0,0 +1,88 @@
+ subroutine hbin(x,y,cell,cnt,xcm,ycm, size, shape,
+ * rx,ry, bnd, n, cellid)
+
+C Copyright 1991
+C Version Date: September 16, 1994
+C Programmer: Dan Carr
+C Indexing: Left to right, bottom to top
+C bnd(1) rows, bnd(2) columns
+C Output: cell ids for non empty cells, revised bnd(1)
+
+c optionally also return cellid(1:n)
+c Copyright (2004) Nicholas Lewin-Koh and Martin Maechler
+
+ implicit none
+
+ integer n, nc, cell(*), cnt(*), bnd(2), cellid(*)
+c cellid(*): length 1 or n
+ double precision x(n), y(n), xcm(*),ycm(*), rx(2),ry(2), size
+ double precision shape
+ integer i, i1, i2, iinc
+ integer j1, j2, jinc
+ integer L, lmax, lat
+ double precision c1, c2, con1, con2, dist1
+ double precision sx, sy, xmin, ymin, xr, yr
+ logical keepID
+
+ keepID = (cellid(1) .eq. 0)
+C_______Constants for scaling the data_____________________________
+
+ xmin = rx(1)
+ ymin = ry(1)
+ xr = rx(2)-xmin
+ yr = ry(2)-ymin
+ c1 = size/xr
+ c2 = size*shape/(yr*sqrt(3.))
+
+ jinc= bnd(2)
+ lat=jinc+1
+ iinc= 2*jinc
+ lmax=bnd(1)*bnd(2)
+ con1=.25
+ con2=1.0/3.0
+
+C_______Binning loop________________________________________
+
+ do i=1,n
+ sx = c1 * (x(i) - xmin)
+ sy = c2 * (y(i) - ymin)
+ j1 = sx+.5
+ i1 = sy+.5
+ dist1=(sx-j1)**2 + 3.*(sy-i1)**2
+
+ if(dist1 .lt. con1) then
+ L=i1*iinc + j1+1
+ elseif(dist1 .gt. con2) then
+ L=int(sy)*iinc + int(sx)+lat
+ else
+ j2 = sx
+ i2 = sy
+ if(dist1 .le. (sx-j2 -.5)**2 + 3.*(sy-i2 -.5)**2) then
+ L=i1*iinc+ j1+1
+ else
+ L=i2*iinc+ j2+lat
+ endif
+ endif
+
+ cnt(L)=cnt(L)+1
+ if (keepID) cellid(i)=L
+ xcm(L)=xcm(L)+ (x(i)-xcm(L))/cnt(L)
+ ycm(L)=ycm(L)+ (y(i)-ycm(L))/cnt(L)
+ enddo
+
+C_______Compression of output________________________________________
+
+ nc=0
+ do L=1,lmax
+ if(cnt(L) .gt. 0) then
+ nc=nc+1
+ cell(nc)=L
+ cnt(nc)=cnt(L)
+ xcm(nc)=xcm(L)
+ ycm(nc)=ycm(L)
+ endif
+ enddo
+ n=nc
+ bnd(1)=(cell(nc)-1)/bnd(2)+1
+ return
+ end
diff --git a/src/hcell.f b/src/hcell.f
new file mode 100644
index 0000000..2d6c78b
--- /dev/null
+++ b/src/hcell.f
@@ -0,0 +1,62 @@
+ subroutine hcell(x,y,cell,n,size,shape,rx,ry,bnd)
+C Copyright 1991
+C Version Date: September 16, 1994
+C Programmer: Dan Carr
+C Indexing: Left to right, bottom to top
+C bnd(1) rows, bnd(2) columns
+C Output: cell ids for none empty cells, revised bnd(1)
+
+c implicit none
+ integer n, cell(1), bnd(2)
+ double precision x(1), y(1), rx(2), ry(2), size, shape
+ integer i, i1, i2, iinc
+ integer j1, j2, jinc
+ integer L, lat, celmax
+ double precision c1, c2, con1, con2, dist1
+ double precision sx, sy, xmin, ymin, xr, yr
+
+C_______Constants for scaling the data_____________________________
+
+ xmin = rx(1)
+ ymin = ry(1)
+ xr = rx(2)-xmin
+ yr = ry(2)-ymin
+ c1 = size/xr
+ c2 = size*shape/(yr*sqrt(3.))
+
+ jinc= bnd(2)
+ lat=jinc+1
+ iinc= 2*jinc
+ con1=.25
+ con2=1./3.
+ celmax=0
+
+C_______Binning loop________________________________________
+
+ do i=1,n
+ sx = c1 * (x(i) - xmin)
+ sy = c2 * (y(i) - ymin)
+ j1 = sx+.5
+ i1 = sy+.5
+ dist1=(sx-j1)**2 + 3.*(sy-i1)**2
+
+ if(dist1.lt.con1)then
+ L=i1*iinc+j1+1
+ elseif(dist1.gt.con2)then
+ L=int(sy)*iinc + int(sx)+lat
+ else
+ j2 = sx
+ i2 = sy
+ if( dist1.le.(sx-j2-.5)**2 + 3. * (sy - i2 -.5)**2) then
+ L=i1*iinc+j1+1
+ else
+ L=i2*iinc+j2+lat
+ endif
+ endif
+
+ cell(i)=L
+ celmax = max(celmax,L)
+ enddo
+ bnd(1)=(celmax-1)/bnd(2)+1
+ return
+ end
diff --git a/src/herode.f b/src/herode.f
new file mode 100644
index 0000000..08f2423
--- /dev/null
+++ b/src/herode.f
@@ -0,0 +1,245 @@
+C File: herode.f
+C Version date: Jan 4, 1994
+C Programmer: Daniel B. Carr
+C
+C The vector erode returns the gray-level erosion order for hexagon cells.
+C The erosion cycle is:
+C cycle = (erode-1)/6 + 1
+C Many cells may be eroded in the same cycle
+C A tie break is the cell count deficit at erosion time:
+C deficit=erode - 6*cycle
+C The last eroded cell might be considered a bivariate median
+C
+C The algorithm:
+C Repeat until no cells are left in the list.
+C Process list
+C Reduce the cell counts by the a multiple of exposed sides
+C If a cell count is zero or less after an erosion cycle
+C let order=order + 6
+C report erode = order + cell count (count is <= 0)
+C remove the cell from consideration
+C update exposed side counts for existing neighbor cells
+C if exposed sides was zero, temporarily store id's
+C else
+C compress list
+C endif
+C Add temporarily stored id's to list
+C End Repeat
+
+ subroutine herode(cell,cnt,n,bdim,
+ * erode,ncnt,ncell,sides,neib,exist)
+
+C
+C
+ implicit none
+
+ integer cell(*), cnt(*) ! cell id and count
+ integer n, bdim(2) ! number of cells and 2-D array bounds
+ integer erode(*) ! erosion status
+ integer ncell(*),ncnt(*) ! extracted id's and expanded counts
+ integer sides(*) ! number of exposed sides
+ integer neib(6,*) ! pointers to the neighbors
+ logical exist(0:*) ! cell existence
+
+ integer nrow, ncol, Lmax ! dimensions
+ integer inc1(6), inc2(6) ! increments to get neighbors
+ integer i, icell, j, k, L ! subscripts
+ integer nc, nnc, nb, ninc, r, c !more subscripts
+ integer loop, order, maxcnt
+
+
+C_______Zero cell ordering numbers________________________________
+
+ order=0
+
+C_______Load the increment arrays and constants
+
+ nrow = bdim(1)
+ ncol = bdim(2)
+ Lmax = nrow * ncol
+ nnc = n
+
+C______Load increment arrays to neigbors______________
+C
+C order=right, up left, down left, up right, left, down right
+
+ inc1(1)= 1
+ inc1(2)= ncol-1
+ inc1(3)= -ncol-1
+ inc1(4)= ncol
+ inc1(5)=-1
+ inc1(6)= -ncol
+
+ inc2(1)= 1
+ inc2(2)= ncol
+ inc2(3)= -ncol
+ inc2(4)= ncol+1
+ inc2(5)=-1
+ inc2(6)= -ncol+1
+
+
+c_______load working arrays_______________________________________________
+
+ do i=0,Lmax
+ exist(i)=.false.
+ enddo
+
+ maxcnt=0
+ do i=1,n
+ icell=cell(i)
+ ncnt(icell)=cnt(i)
+ exist(icell)=.true.
+ maxcnt=max(maxcnt,cnt(i))
+ enddo
+
+C_______Store pointers to cell neighbors_________________________
+C
+C A pointer of 0 means the neigbor in out of bounds
+C Also find the max count
+C Speed: Can avoid adding 1's to r and c
+C but this code is easier to follow
+ do i=1,n
+ L=cell(i)
+ k = L -1
+ r=k/ncol+1
+ c=mod(k,ncol)+1
+ if(mod(r,2).eq.1)then
+ do j = 1,6
+ neib(j,L) = L + inc1(j)
+ enddo
+
+ if (c .eq. 1) then
+ neib(2,L) = 0
+ neib(3,L) = 0
+ neib(5,L) = 0
+ else if (c .eq. ncol) then
+ neib(1,L) = 0
+ endif
+
+ if (r .eq. 1) then
+ neib(3,L) = 0
+ neib(6,L) = 0
+ else if(r.eq.nrow)then
+ neib(2,L) = 0
+ neib(4,L) =0
+ endif
+
+ else
+ do j= 1,6
+ neib(j,L) = L + inc2(j)
+ enddo
+
+ if (c .eq. 1) then
+ neib(5,L) = 0
+ else if (c .eq. ncol) then
+ neib(1,L) = 0
+ neib(4,L) = 0
+ neib(6,L) = 0
+ endif
+
+ if (r .eq. nrow) then
+ neib(2,L) = 0
+ neib(4,L) = 0
+ endif
+
+ endif
+ enddo
+
+
+C_______Count exposed sides for cells in the contour_________________
+
+ do i=1,n
+ icell=cell(i)
+ sides(icell)=0
+ do j=1,6
+ if(.not. exist( neib(j,icell) ) )then
+ sides(icell)=sides(icell)+ 1
+ endif
+ enddo
+ enddo
+
+C________Grab surface cells___________________________________________
+
+ nc=0
+ do i=1,n
+ if(sides(cell(i)).gt.0)then
+ nc=nc+1
+ ncell(nc)=cell(i)
+ endif
+ enddo
+ n=nc !n is now the number of exposed, non-empty cells
+
+C_______The outer loop________________________________________________
+C
+C temporary indices
+C nc: index for cells remaining on the list
+C ninc: index for newly exposed cells added to back of list
+
+ do while(n.gt.0)
+
+C Subtract exposed-side counts from the surface cell counts
+C until at least one cell is empty.
+
+ loop=maxcnt
+ do i=1,n
+ icell=ncell(i)
+ loop=min( (ncnt(icell)-1)/sides(icell) , loop)
+ enddo
+ loop=loop+1 !all loop values are 1 too small
+
+C update the counts, rank and remove eroded cells
+
+ nc=0
+ order=order+6
+ ninc=n
+ do i=1,n
+ icell=ncell(i)
+ ncnt(icell)=ncnt(icell)-sides(icell)*loop
+ if(ncnt(icell).le.0)then
+
+C Remove the empty cell and store it's order
+ exist(icell)=.false.
+ erode(icell)=order+ncnt(icell)
+
+C Update the neighbors of the empty cell
+ do j=1,6
+ nb=neib(j,icell)
+ if(exist(nb))then
+
+C Store cells for addition to surface list
+ if(sides(nb).eq.0)then
+ ninc=ninc+1
+ ncell(ninc)=nb
+ endif
+
+C Update sides for the neighbors
+ sides(nb)=sides(nb)+1
+ endif
+ enddo
+ else
+
+C Save remaining cells
+ nc=nc+1
+ ncell(nc)=ncell(i)
+ endif
+ enddo
+
+C Add new surface cells if any
+
+ do i=n+1,ninc,1
+ nc=nc+1
+ ncell(nc)=ncell(i)
+ enddo
+ n=nc
+ enddo
+
+C_______compress result___________________________________________
+
+
+ do i=1,nnc
+ erode(i)=erode(cell(i))
+ enddo
+ n=nnc
+
+ return
+ end
diff --git a/src/hsm.f b/src/hsm.f
new file mode 100644
index 0000000..b282cc0
--- /dev/null
+++ b/src/hsm.f
@@ -0,0 +1,114 @@
+C File: hsm.f
+C Programmer: Daniel B. Carr
+C Version Date: January 3, 1994
+C
+C This program is an hexagon cell smoother. It smooths into
+C neighboring cells and hence expands.
+
+C The kernal is a crude integer kernel.
+C The boundary hexagons get weight 1, the center hexagon
+C gets weight, wt, which by default is set to six.
+C
+C
+
+ subroutine hsm(cell,cnt,n,nmax,sm,ncol,wt)
+
+ implicit none
+
+ integer n, nmax, ncol
+ integer cell(*), cnt(*), sm(*), wt(*)
+ integer ind, ind1(6), ind2(12),ind3(6), ind4(12), loc
+ integer row, cnt1, cnt2, wta, wtb, wtc
+ integer i, j
+
+C__________Constants___________________________________________
+
+ ind1(1)=-1
+ ind1(2)=ncol-1
+ ind1(3)=ncol
+ ind1(4)=+1
+ ind1(5)=-ncol
+ ind1(6)=-ncol-1
+
+ ind2(1)=-2
+ ind2(2)=ncol-2
+ ind2(3)=2*ncol-1
+ ind2(4)=2*ncol
+ ind2(5)=2*ncol+1
+ ind2(6)=ncol+1
+ ind2(7)=2
+ ind2(8)=-ncol+1
+ ind2(9)=-2*ncol+1
+ ind2(10)=-2*ncol
+ ind2(11)=-2*ncol-1
+ ind2(12)=-ncol-2
+
+ ind3(1)=-1
+ ind3(2)=ncol
+ ind3(3)=ncol+1
+ ind3(4)=+1
+ ind3(5)=-ncol+1
+ ind3(6)=-ncol
+
+ ind4(1)=-2
+ ind4(2)=ncol-1
+ ind4(3)=2*ncol-1
+ ind4(4)=2*ncol
+ ind4(5)=2*ncol+1
+ ind4(6)=ncol+2
+ ind4(7)=2
+ ind4(8)=-ncol+2
+ ind4(9)=-2*ncol+1
+ ind4(10)=-2*ncol
+ ind4(11)=-2*ncol-1
+ ind4(12)=-ncol-1
+
+ wta = wt(1)
+ wtb = wt(2)
+ wtc = wt(3)
+
+C_________Smoothing_____________________________________
+
+ do i=1,n
+ sm(cell(i))=wta*cnt(i)
+ enddo
+
+ do i=1,n
+ loc=cell(i)
+ row=(loc-1)/ncol + 1
+ cnt1=wtb*cnt(i)
+ cnt2=wtc*cnt(i)
+
+ if(mod(row,2).eq.1)then
+ do j=1,6
+ ind=loc+ind1(j)
+ sm(ind)=sm(ind)+cnt1
+ enddo
+ do j=1,12
+ ind=loc+ind2(j)
+ sm(ind)=sm(ind)+cnt2
+ enddo
+ else
+ do j=1,6
+ ind=loc+ind3(j)
+ sm(ind)=sm(ind)+cnt1
+ enddo
+ do j=1,12
+ ind=loc+ind4(j)
+ sm(ind)=sm(ind)+cnt2
+ enddo
+ endif
+ enddo
+
+ n=0
+ do i=1,nmax
+ if(sm(i).gt.0)then
+ n=n+1
+ cell(n)=i
+ cnt(n)=sm(i)
+ endif
+ enddo
+ return
+ end
+
+
diff --git a/tests/hdiffplot.R b/tests/hdiffplot.R
new file mode 100644
index 0000000..921d061
--- /dev/null
+++ b/tests/hdiffplot.R
@@ -0,0 +1,36 @@
+library(hexbin)
+
+if(R.version$major != "1" || as.numeric(R.version$minor) >= 7)
+ RNGversion("1.6")
+set.seed(213)
+x1 <- rnorm(10000)
+y1 <- rnorm(10000)
+
+x2 <- rnorm(10000,mean = .3)
+y2 <- rnorm(10000,mean = .3)
+
+rx <- range(x1,x2)
+ry <- range(y1,y2)
+
+str(bin1 <- hexbin(x1,y1, xbnds = rx, ybnds = ry))
+str(bin2 <- hexbin(x2,y2, xbnds = rx, ybnds = ry))
+
+str(erode(bin1))
+
+str(smbin1 <- smooth.hexbin(bin1))
+(smbin2 <- smooth.hexbin(bin2))
+
+str(erodebin1 <- erode.hexbin(smbin1))
+(erodebin2 <- erode.hexbin(smbin2))
+
+if(FALSE)## does not work -- what funny stuff is hdiffplot() doing???
+ par(mfrow = c(2,1))
+
+if(exists("hdiffplot", mode="function")) { ## not yet in new hexbin
+hdiffplot(bin1,bin2, main = "Original N(0,*) Random bins")
+
+hdiffplot(smbin1,smbin2, main = "smooth.hexbin() smoothed bins")
+
+plot.new()
+hdiffplot(erodebin1,erodebin2, main = "erode.hexbin()d smoothed bins")
+}# not yet
diff --git a/tests/hdiffplot.Rout.save b/tests/hdiffplot.Rout.save
new file mode 100644
index 0000000..89706a5
--- /dev/null
+++ b/tests/hdiffplot.Rout.save
@@ -0,0 +1,155 @@
+
+R Under development (unstable) (2013-01-29 r61780) -- "Unsuffered Consequences"
+Copyright (C) 2013 The R Foundation for Statistical Computing
+ISBN 3-900051-07-0
+
+R is free software and comes with ABSOLUTELY NO WARRANTY.
+You are welcome to redistribute it under certain conditions.
+Type 'license()' or 'licence()' for distribution details.
+
+R is a collaborative project with many contributors.
+Type 'contributors()' for more information and
+'citation()' on how to cite R or R packages in publications.
+
+Type 'demo()' for some demos, 'help()' for on-line help, or
+'help.start()' for an HTML browser interface to help.
+Type 'q()' to quit R.
+
+> library(hexbin)
+Loading required package: grid
+Loading required package: lattice
+>
+> if(R.version$major != "1" || as.numeric(R.version$minor) >= 7)
++ RNGversion("1.6")
+Warning message:
+In RNGkind("Marsaglia-Multicarry", "Buggy Kinderman-Ramage") :
+ buggy version of Kinderman-Ramage generator used
+> set.seed(213)
+> x1 <- rnorm(10000)
+> y1 <- rnorm(10000)
+>
+> x2 <- rnorm(10000,mean = .3)
+> y2 <- rnorm(10000,mean = .3)
+>
+> rx <- range(x1,x2)
+> ry <- range(y1,y2)
+>
+> str(bin1 <- hexbin(x1,y1, xbnds = rx, ybnds = ry))
+Formal class 'hexbin' [package "hexbin"] with 16 slots
+ ..@ cell : int [1:535] 16 20 48 70 74 75 76 80 99 101 ...
+ ..@ count : int [1:535] 1 1 1 1 1 1 1 1 1 1 ...
+ ..@ xcm : num [1:535] 0.37 1.338 0.721 -1.846 -0.965 ...
+ ..@ ycm : num [1:535] -3.66 -3.71 -3.54 -3.2 -3.24 ...
+ ..@ xbins : num 30
+ ..@ shape : num 1
+ ..@ xbnds : num [1:2] -3.8 4.3
+ ..@ ybnds : num [1:2] -3.71 4.17
+ ..@ dimen : num [1:2] 36 31
+ ..@ n : int 10000
+ ..@ ncells: int 535
+ ..@ call : language hexbin(x = x1, y = y1, xbnds = rx, ybnds = ry)
+ ..@ xlab : chr "x1"
+ ..@ ylab : chr "y1"
+ ..@ cID : NULL
+ ..@ cAtt : int(0)
+> str(bin2 <- hexbin(x2,y2, xbnds = rx, ybnds = ry))
+Formal class 'hexbin' [package "hexbin"] with 16 slots
+ ..@ cell : int [1:545] 41 51 75 76 104 107 110 114 136 138 ...
+ ..@ count : int [1:545] 1 1 1 1 1 2 1 1 2 1 ...
+ ..@ xcm : num [1:545] -1.141 1.445 -0.493 -0.324 -0.995 ...
+ ..@ ycm : num [1:545] -3.42 -3.45 -3.24 -3.35 -2.9 ...
+ ..@ xbins : num 30
+ ..@ shape : num 1
+ ..@ xbnds : num [1:2] -3.8 4.3
+ ..@ ybnds : num [1:2] -3.71 4.17
+ ..@ dimen : num [1:2] 36 31
+ ..@ n : int 10000
+ ..@ ncells: int 545
+ ..@ call : language hexbin(x = x2, y = y2, xbnds = rx, ybnds = ry)
+ ..@ xlab : chr "x2"
+ ..@ ylab : chr "y2"
+ ..@ cID : NULL
+ ..@ cAtt : int(0)
+>
+> str(erode(bin1))
+Formal class 'erodebin' [package "hexbin"] with 19 slots
+ ..@ eroded: logi [1:535] FALSE FALSE FALSE FALSE FALSE FALSE ...
+ ..@ cdfcut: num 0.5
+ ..@ erode : int [1:71] 12 35 34 57 52 4 30 101 138 150 ...
+ ..@ cell : int [1:535] 16 20 48 70 74 75 76 80 99 101 ...
+ ..@ count : int [1:535] 1 1 1 1 1 1 1 1 1 1 ...
+ ..@ xcm : num [1:535] 0.37 1.338 0.721 -1.846 -0.965 ...
+ ..@ ycm : num [1:535] -3.66 -3.71 -3.54 -3.2 -3.24 ...
+ ..@ xbins : num 30
+ ..@ shape : num 1
+ ..@ xbnds : num [1:2] -3.8 4.3
+ ..@ ybnds : num [1:2] -3.71 4.17
+ ..@ dimen : num [1:2] 36 31
+ ..@ n : int 10000
+ ..@ ncells: int 535
+ ..@ call : language hexbin(x = x1, y = y1, xbnds = rx, ybnds = ry)
+ ..@ xlab : chr "x1"
+ ..@ ylab : chr "y1"
+ ..@ cID : NULL
+ ..@ cAtt : int(0)
+>
+> str(smbin1 <- smooth.hexbin(bin1))
+Formal class 'smoothbin' [package "hexbin"] with 17 slots
+ ..@ wts : num [1:3] 48 4 1
+ ..@ cell : int [1:906] 17 18 19 21 22 23 51 52 53 54 ...
+ ..@ count : int [1:906] 1 1 1 1 1 1 1 4 5 2 ...
+ ..@ xcm : num [1:535] 0.37 1.338 0.721 -1.846 -0.965 ...
+ ..@ ycm : num [1:535] -3.66 -3.71 -3.54 -3.2 -3.24 ...
+ ..@ xbins : num 34
+ ..@ shape : num 1
+ ..@ xbnds : num [1:2] -4.34 4.84
+ ..@ ybnds : num [1:2] -4.23 4.7
+ ..@ dimen : num [1:2] 40 35
+ ..@ n : int 10000
+ ..@ ncells: int 535
+ ..@ call : language hexbin(x = x1, y = y1, xbnds = rx, ybnds = ry)
+ ..@ xlab : chr "x1"
+ ..@ ylab : chr "y1"
+ ..@ cID : NULL
+ ..@ cAtt : int(0)
+> (smbin2 <- smooth.hexbin(bin2))
+'hexbin' object from call: hexbin(x = x2, y = y2, xbnds = rx, ybnds = ry)
+n = 10000 points in nc = 545 hexagon cells in grid dimensions 40 by 35
+>
+> str(erodebin1 <- erode.hexbin(smbin1))
+Formal class 'erodebin' [package "hexbin"] with 19 slots
+ ..@ eroded: logi [1:906] FALSE FALSE FALSE FALSE FALSE FALSE ...
+ ..@ cdfcut: num 0.5
+ ..@ erode : int [1:73] 11 35 95 100 117 88 6 39 167 232 ...
+ ..@ cell : int [1:906] 17 18 19 21 22 23 51 52 53 54 ...
+ ..@ count : int [1:906] 1 1 1 1 1 1 1 4 5 2 ...
+ ..@ xcm : num [1:535] 0.37 1.338 0.721 -1.846 -0.965 ...
+ ..@ ycm : num [1:535] -3.66 -3.71 -3.54 -3.2 -3.24 ...
+ ..@ xbins : num 34
+ ..@ shape : num 1
+ ..@ xbnds : num [1:2] -4.34 4.84
+ ..@ ybnds : num [1:2] -4.23 4.7
+ ..@ dimen : num [1:2] 40 35
+ ..@ n : int 10000
+ ..@ ncells: int 535
+ ..@ call : language hexbin(x = x1, y = y1, xbnds = rx, ybnds = ry)
+ ..@ xlab : chr "x1"
+ ..@ ylab : chr "y1"
+ ..@ cID : NULL
+ ..@ cAtt : int(0)
+> (erodebin2 <- erode.hexbin(smbin2))
+'hexbin' object from call: hexbin(x = x2, y = y2, xbnds = rx, ybnds = ry)
+n = 10000 points in nc = 545 hexagon cells in grid dimensions 40 by 35
+>
+> if(FALSE)## does not work -- what funny stuff is hdiffplot() doing???
++ par(mfrow = c(2,1))
+>
+> if(exists("hdiffplot", mode="function")) { ## not yet in new hexbin
++ hdiffplot(bin1,bin2, main = "Original N(0,*) Random bins")
++
++ hdiffplot(smbin1,smbin2, main = "smooth.hexbin() smoothed bins")
++
++ plot.new()
++ hdiffplot(erodebin1,erodebin2, main = "erode.hexbin()d smoothed bins")
++ }# not yet
+>
diff --git a/tests/hray.R b/tests/hray.R
new file mode 100644
index 0000000..13a9cce
--- /dev/null
+++ b/tests/hray.R
@@ -0,0 +1,31 @@
+library(hexbin)
+
+set.seed(572)
+
+x <- rnorm(100)
+y <- rnorm(100)
+val <- rnorm(100)
+inc <- abs(rnorm(100,sd = .3))
+loB <- val-inc
+hiB <- val+inc
+
+if(exists("hray", mode="function")) { # 'real soon now'
+
+## no confidence bounds
+plot(x,y,type = 'n')
+hray(x,y,val)
+
+## confidence bounds
+plot(x,y,type = 'n')
+hray(x,y,val, lo = loB, hi = hiB)
+
+## clockwise orientation
+plot(x,y,type = 'n')
+hray(x,y,val, loB, hiB, clockwise = TRUE)
+
+## no tics and small filled dots
+plot(x,y,type = 'n')
+hray(x,y,val, loB, hiB, ticlength = FALSE,
+ dotside = 20, dotlength = .025, dotden = -1)
+
+}
diff --git a/tests/hray.Rout.save b/tests/hray.Rout.save
new file mode 100644
index 0000000..35c9748
--- /dev/null
+++ b/tests/hray.Rout.save
@@ -0,0 +1,52 @@
+
+R version 3.1.1 (2014-07-10) -- "Sock it to Me"
+Copyright (C) 2014 The R Foundation for Statistical Computing
+Platform: x86_64-pc-linux-gnu (64-bit)
+
+R is free software and comes with ABSOLUTELY NO WARRANTY.
+You are welcome to redistribute it under certain conditions.
+Type 'license()' or 'licence()' for distribution details.
+
+R is a collaborative project with many contributors.
+Type 'contributors()' for more information and
+'citation()' on how to cite R or R packages in publications.
+
+Type 'demo()' for some demos, 'help()' for on-line help, or
+'help.start()' for an HTML browser interface to help.
+Type 'q()' to quit R.
+
+> library(hexbin)
+>
+> set.seed(572)
+>
+> x <- rnorm(100)
+> y <- rnorm(100)
+> val <- rnorm(100)
+> inc <- abs(rnorm(100,sd = .3))
+> loB <- val-inc
+> hiB <- val+inc
+>
+> if(exists("hray", mode="function")) { # 'real soon now'
++
++ ## no confidence bounds
++ plot(x,y,type = 'n')
++ hray(x,y,val)
++
++ ## confidence bounds
++ plot(x,y,type = 'n')
++ hray(x,y,val, lo = loB, hi = hiB)
++
++ ## clockwise orientation
++ plot(x,y,type = 'n')
++ hray(x,y,val, loB, hiB, clockwise = TRUE)
++
++ ## no tics and small filled dots
++ plot(x,y,type = 'n')
++ hray(x,y,val, loB, hiB, ticlength = FALSE,
++ dotside = 20, dotlength = .025, dotden = -1)
++
++ }
+>
+> proc.time()
+ user system elapsed
+ 0.252 0.012 0.258
diff --git a/tests/large.R b/tests/large.R
new file mode 100644
index 0000000..aa42e04
--- /dev/null
+++ b/tests/large.R
@@ -0,0 +1,39 @@
+library(hexbin)
+
+if(FALSE) { ## the following is still quite a bit from working/useful :
+
+## what should that do? set a palette?
+rgb <- matrix(c(
+ 15,15,15,
+
+ 0, 0, 0,
+ 1, 9,15,
+ 9,15, 9,
+ 15, 9, 9,
+
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0,
+
+ 9, 9, 9,
+ 0, 2, 7,
+ 0, 7, 1,
+ 8, 1, 1,
+
+ 15, 2, 2,
+ 11, 1, 1,
+ 8, 1, 1,
+ 5, 1, 1,
+ 5, 1, 1,
+ 15,15,15), ncol = 3, byrow = TRUE)
+
+##ps.options(rasters=600,color=rgb/15,background=2)
+##ps.options(color=rgb/15,background=2)
+postscript("large.ps",width = 10,height = 7.5)
+
+plot.hexbin(ans.25mil, style = "nest", lcex = .9)
+
+}## FALSE, i.e. nothing done
diff --git a/tests/large.Rout.save b/tests/large.Rout.save
new file mode 100644
index 0000000..5081e01
--- /dev/null
+++ b/tests/large.Rout.save
@@ -0,0 +1,60 @@
+
+R version 3.1.1 (2014-07-10) -- "Sock it to Me"
+Copyright (C) 2014 The R Foundation for Statistical Computing
+Platform: x86_64-pc-linux-gnu (64-bit)
+
+R is free software and comes with ABSOLUTELY NO WARRANTY.
+You are welcome to redistribute it under certain conditions.
+Type 'license()' or 'licence()' for distribution details.
+
+R is a collaborative project with many contributors.
+Type 'contributors()' for more information and
+'citation()' on how to cite R or R packages in publications.
+
+Type 'demo()' for some demos, 'help()' for on-line help, or
+'help.start()' for an HTML browser interface to help.
+Type 'q()' to quit R.
+
+> library(hexbin)
+>
+> if(FALSE) { ## the following is still quite a bit from working/useful :
++
++ ## what should that do? set a palette?
++ rgb <- matrix(c(
++ 15,15,15,
++
++ 0, 0, 0,
++ 1, 9,15,
++ 9,15, 9,
++ 15, 9, 9,
++
++ 0, 0, 0,
++ 0, 0, 0,
++ 0, 0, 0,
++ 0, 0, 0,
++ 0, 0, 0,
++ 0, 0, 0,
++
++ 9, 9, 9,
++ 0, 2, 7,
++ 0, 7, 1,
++ 8, 1, 1,
++
++ 15, 2, 2,
++ 11, 1, 1,
++ 8, 1, 1,
++ 5, 1, 1,
++ 5, 1, 1,
++ 15,15,15), ncol = 3, byrow = TRUE)
++
++ ##ps.options(rasters=600,color=rgb/15,background=2)
++ ##ps.options(color=rgb/15,background=2)
++ postscript("large.ps",width = 10,height = 7.5)
++
++ plot.hexbin(ans.25mil, style = "nest", lcex = .9)
++
++ }## FALSE, i.e. nothing done
+>
+> proc.time()
+ user system elapsed
+ 0.240 0.032 0.265
diff --git a/tests/viewp-ex.R b/tests/viewp-ex.R
new file mode 100644
index 0000000..1983963
--- /dev/null
+++ b/tests/viewp-ex.R
@@ -0,0 +1,21 @@
+library(hexbin)
+
+## a variation on Nicholas' post to bioconductor & example(hexViewport)
+set.seed(545)
+x <- rnorm(2^15)
+y <- 3*x - .2*x^2 + rnorm(2^15)
+hbin <- hexbin(x,y)
+
+##
+hp <- hexViewport(hbin, newpage = TRUE)
+pushHexport(hp)
+library("grid")
+grid.rect()
+grid.xaxis()
+grid.yaxis()
+grid.hexagons(hbin, style = "centroid")
+hloess <- loess(y ~ x, data = hcell2xy(hbin), weights = hbin @ count)
+xx <- seq(hbin at xbnds[1], hbin at xbnds[2], length = 500)
+grid.lines(xx, predict(hloess, xx),
+ gp = gpar(col = 'red', lwd = 2), default.units = "native")
+popViewport()
diff --git a/tests/viewp-ex.Rout.save b/tests/viewp-ex.Rout.save
new file mode 100644
index 0000000..a2806ca
--- /dev/null
+++ b/tests/viewp-ex.Rout.save
@@ -0,0 +1,42 @@
+
+R version 3.1.1 (2014-07-10) -- "Sock it to Me"
+Copyright (C) 2014 The R Foundation for Statistical Computing
+Platform: x86_64-pc-linux-gnu (64-bit)
+
+R is free software and comes with ABSOLUTELY NO WARRANTY.
+You are welcome to redistribute it under certain conditions.
+Type 'license()' or 'licence()' for distribution details.
+
+R is a collaborative project with many contributors.
+Type 'contributors()' for more information and
+'citation()' on how to cite R or R packages in publications.
+
+Type 'demo()' for some demos, 'help()' for on-line help, or
+'help.start()' for an HTML browser interface to help.
+Type 'q()' to quit R.
+
+> library(hexbin)
+>
+> ## a variation on Nicholas' post to bioconductor & example(hexViewport)
+> set.seed(545)
+> x <- rnorm(2^15)
+> y <- 3*x - .2*x^2 + rnorm(2^15)
+> hbin <- hexbin(x,y)
+>
+> ##
+> hp <- hexViewport(hbin, newpage = TRUE)
+> pushHexport(hp)
+> library("grid")
+> grid.rect()
+> grid.xaxis()
+> grid.yaxis()
+> grid.hexagons(hbin, style = "centroid")
+> hloess <- loess(y ~ x, data = hcell2xy(hbin), weights = hbin @ count)
+> xx <- seq(hbin at xbnds[1], hbin at xbnds[2], length = 500)
+> grid.lines(xx, predict(hloess, xx),
++ gp = gpar(col = 'red', lwd = 2), default.units = "native")
+> popViewport()
+>
+> proc.time()
+ user system elapsed
+ 0.368 0.020 0.379
diff --git a/vignettes/hexagon_binning.Rnw b/vignettes/hexagon_binning.Rnw
new file mode 100644
index 0000000..928a584
--- /dev/null
+++ b/vignettes/hexagon_binning.Rnw
@@ -0,0 +1,502 @@
+%% Emacs: use Rnw-mode if available, else noweb
+%% NOTE -- ONLY EDIT THE .Rnw FILE !
+
+%\VignetteIndexEntry{Hexagon Binning}
+%\VignetteDepends{hexbin, grid, marray}
+%\VignetteKeywords{Over plotting, Large data set, Visualization}
+%\VignettePackage{hexbin}
+
+\documentclass[]{article}
+
+\usepackage[authoryear,round]{natbib}
+\usepackage{amsmath}
+\usepackage{hyperref}
+
+
+\author{Nicholas Lewin-Koh\footnote{with minor assistance by Martin M\"achler}}
+
+\begin{document}
+
+\title{Hexagon Binning: an Overview}
+\maketitle{}
+
+\section{Overview}
+Hexagon binning is a form of bivariate histogram useful for visualizing
+the structure in datasets with large $n$. The underlying concept of
+hexagon binning is extremely simple;
+\begin{enumerate}
+\item the $xy$ plane over the set (range($x$), range($y$)) is tessellated
+by a regular grid of hexagons.
+
+\item the number of points falling in each hexagon are counted and
+stored in a data structure
+
+\item the hexagons with count $ > 0$ are plotted using a color ramp or
+varying the radius of the hexagon in proportion to the counts.
+\end{enumerate}
+
+The underlying algorithm is extremely fast and effective for displaying
+the structure of datasets with $n \ge 10^6$.
+If the size of the grid and the cuts in the color ramp are chosen in a
+clever fashion than the structure inherent in the data should emerge
+in the binned plots. The same caveats apply to hexagon binning as
+apply to histograms and care should be exercised in choosing the
+binning parameters.
+
+The hexbin package is a set of function for creating, manipulating and
+plotting hexagon bins. The package extends the basic hexagon binning
+ideas with several functions for doing bivariate smoothing, finding an
+approximate bivariate median, and looking at the difference between
+two sets of bins on the same scale. The basic functions can be
+incorporated into many types of plots. This package is based on the
+original package for S-PLUS by Dan Carr at George Mason University and
+is mostly the fruit of his graphical genius and intuition.
+
+\section{Theory and Algorithm}
+Why hexagons? There are many reasons for using hexagons, at least over
+squares. Hexagons have symmetry of nearest neighbors which is lacking
+in square bins. Hexagons are the maximum number of sides a polygon can
+have for a regular tesselation of the plane, so in terms of packing a
+hexagon is 13\% more efficient for covering the plane than
+squares. This property translates into better sampling efficiency at
+least for elliptical shapes. Lastly hexagons are visually less biased
+for displaying densities than other regular tesselations. For instance
+with squares our eyes are drawn to the horizontal and vertical lines
+of the grid. The following figure adapted from \cite[]{carretal}shows
+this effectively.
+
+\begin{figure}[h]
+ \centering
+<<comphexsq, fig=TRUE, width=7, height=4, echo=FALSE>>=
+library("grid")
+library("hexbin")
+x <- rnorm(1000)
+y <- rnorm(1000)
+##-- Hexagon Bins: --
+hbin <- hexbin(x,y, xbins = 25)
+grid.newpage()
+pushViewport(viewport(layout=grid.layout(1, 2)))
+pushViewport(viewport(layout.pos.col=1,layout.pos.row=1))
+plot(hbin, style="lattice", legend=0, xlab = "X", ylab = "Y", newpage=FALSE)
+popViewport()
+
+##-- Manual "square" binning: --
+## grid
+rx <- range(x); bx <- seq(rx[1],rx[2], length=29)
+ry <- range(y); by <- seq(ry[1],ry[2], length=29)
+## midpoints
+mx <- (bx[-1]+bx[-29])/2
+my <- (by[-1]+by[-29])/2
+gg <- as.matrix(expand.grid(mx,my))# dim = (28^2, 2)
+zz <- unname(table(cut(x, b = bx), cut(y, b = by)))# 28 x 28
+ind <- zz > 0
+if(FALSE) ## ASCII image:
+ symnum(unname(ind))
+sq.size <- zz[ind]^(1/3) / max(zz)
+## if we used base graphics:
+## symbols(gg[ind,], squares = sq.size, inches = FALSE, fg = 2, bg = 2)
+pushViewport(viewport(layout.pos.col=2, layout.pos.row=1))
+vp <- plot(hbin, style="lattice", legend=0,
+ xlab = "X", ylab = "Y", newpage=FALSE, type="n")
+pushHexport(vp$plot, clip="on")
+grid.rect(x= gg[ind,1], y=gg[ind,2], width = sq.size, height= sq.size,
+ default.units = "native", gp = gpar(col="black",fill="black"))
+popViewport()
+@
+ \caption[bivariate: squares and hexagons]{A bivariate point set binned
+ into squares and hexagons. Bins are
+ scaled approximately equal, and the size of the glyph is proportional
+ to the count in that bin.}
+ \label{fig:compHexSq}
+\end{figure}
+
+
+We can see in Figure~\ref{fig:compHexSq} that when the data are plotted
+as squares centered on a regular lattice our eye is drawn to the regular lines
+which are parallel to the underlying grid. Hexagons tend to break up
+the lines.
+
+How does does the hexagon binning algorithm work?
+
+\begin{enumerate}
+\item Squash $Y$ by $\sqrt{3}$
+\item Create a dual lattice
+\item Bin each point into pair of near neighbor rectangles
+\item Pick closest of the rectangle centers (adjusting for $\sqrt{3}$)
+\end{enumerate}
+
+
+<< nearNeighbor, echo = false, results = hide >>=
+x <- -2:2
+sq <- expand.grid(list(x = x, y = c(-1,0,1)))
+fc.sq <- rbind(sq,sq+.5) # face centered squares
+fc.sq$y <- sqrt(3)*fc.sq$y # stretch y by the sqrt(3)
+nr <- length(fc.sq$x)/2
+@
+
+\begin{figure}[h]
+ \centering
+<< fig = TRUE,width = 4,height = 8,echo = FALSE >>=
+par(mfrow = c(3,1))
+par(mai = c(.1667,0.2680,0.1667,0.2680)) ##par(mai=.25*par("mai"))
+plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5)
+nr <- length(fc.sq$x)/2
+points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5)
+points(-.25,.15, col = 2, pch = 16, cex = .5)
+
+par(mai = c(.1667, 0.2680, 0.1667, 0.2680))##par(mai=.25*par("mai"))
+plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5)
+nr <- length(fc.sq$x)/2
+points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5)
+px <- c(-1,-2,-2,-1)+1
+py <- sqrt(3)*(c(0,0,-1,-1)+1)
+polygon(px, py, density = 0, col = 5)
+polygon(px+.5, py-sqrt(3)/2, density = 0)
+points(-.25, .15, col = 2, pch = 16, cex = .5)
+
+par(mai = c(.1667, 0.2680, 0.1667, 0.2680))##par(mai=.25*par("mai"))
+plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5)
+nr <- length(fc.sq$x)/2
+points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5)
+px <- c(-1,-2,-2,-1) + 1
+py <- sqrt(3)*(c(0,0,-1,-1) + 1)
+polygon(px, py, density = 0, col = 5)
+polygon(px+.5, py-sqrt(3)/2, density = 0)
+px <- c(-.5,-.5,0,.5, .5, 0)
+py <- c(-.5, .5,1,.5,-.5,-1) /sqrt(3)
+polygon(px, py, col = gray(.5), density = 0)
+polygon(px-.5, py+sqrt(3)/2, density = 0, col = 4)
+points(-.25, .15, col = 2, pch = 16, cex = .5)
+plot.new()
+arrows(-.25, .15, 0, 0, angle = 10, length = .05)
+@
+\caption[Near Neighbor Rectangles]{}
+\label{fig:binalg}
+\end{figure}
+
+Figure~\ref{fig:binalg} shows graphically how the algorithm works. In
+the first panel we see the the dual lattice laid out in black and blue
+points. The red point is an arbitrary point to be binned. The second
+panel shows the near neigbor rectangles for each lattice around the
+point to be binned, the intersection of the rectangles contains the
+point. The last panel shows the simple test for locating the point in
+the hexagon, the closest of the two corners which are not
+intersections is the center of the hexagon to which the point should
+be allocated. The binning can be calculated in one pass through the
+data, and is clearly $O(n)$ with a small constant. Storage is vastly
+reduced compared to the original data.
+
+\section{Basic Hexagon Binning Functions}
+Using the basic hexagon binning functions are not much more involved
+than using the basic plotting functions. The following little example
+shows the basic features of the basic plot and binning functions.
+We start by loading the package and generating a toy example data set.
+
+<< basic, fig = TRUE, results = hide >>=
+x <- rnorm(20000)
+y <- rnorm(20000)
+hbin <- hexbin(x,y, xbins = 40)
+plot(hbin)
+@
+There are two things to note here. The first is that the function
+\texttt{gplot.hexbin} is defined as a \texttt{plot} method for the S4 class
+\texttt{hexbin}. The second is that the default color scheme for the
+hexplot is a gray scale. However, there is an argument to plot,
+\texttt{colramp}, that allows the use of any function that excepts an
+argument \texttt{n} and returns $n$ colors. Several functions are supplied
+that provide alternative color-ramps to R's built in color ramp functions,
+see \texttt{help(ColorRamps)}.
+
+<< showcol, fig = TRUE, width = 7, height = 4, echo = FALSE >>=
+#nf <- layout(matrix(c(1,1,2,2,4,3,3,4), ncol=4, nrow=2, byrow=TRUE),
+# widths = rep(1,4), heights=rep(1,2))
+grid.newpage()
+mar <- unit(0.1 + c(5,4,4,2),"lines")
+mai <- as.numeric(convertUnit(mar, "inches"))
+vpin <- c(convertWidth (unit(1,"npc"),"inches"),
+ convertHeight(unit(1,"npc"),"inches"))
+shape <- optShape(height = vpin[2],width = vpin[1]/3,mar = mai)
+
+x <- rnorm(20000)
+y <- rnorm(20000)
+hbin <- hexbin(x,y, xbins = 40, shape = shape)
+grid.newpage()
+pushViewport(viewport(layout = grid.layout(1, 3)))
+pushViewport(viewport(layout.pos.col = 1,layout.pos.row = 1))
+plot(hbin, legend = 0, xlab = "X", ylab = "Y", newpage = FALSE)
+popViewport()
+pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1))
+plot(hbin, legend = 0, xlab = "X", ylab = "Y",
+ newpage = FALSE, colramp = terrain.colors)
+popViewport()
+pushViewport(viewport(layout.pos.col = 3,layout.pos.row = 1))
+plot(hbin, legend = 0, xlab = "X", ylab = "Y",
+ newpage = FALSE, colramp = BTY)
+popViewport()
+@
+
+The figure shows three examples of using hexagons in a plot for large $n$ with
+different color schemes. Upper left: the default gray scale, upper right: the
+R base \texttt{terrain.colors()}, and lower middle: \texttt{BTY()}, a
+blue to yellow color ramp supplied with hexbin on a perceptually linear
+scale.
+
+The hexbin package supplies a plotting method for the hexbin data
+structure. The plotting method \texttt{gplot.hexbin} accepts all the
+parameters for the hexagon function and supplies a legend as well, for
+easy interpretation of the plot. Figure~2 shows a hex binned plot with
+a legend. A function \texttt{grid.hexlegend} is supplied for creating user
+specified hexagon legends.
+
+\section{Extended Hexagon Functions}
+So far we have looked at the basic hexagon plot. The hexbin package
+supplies several extensions to the basic hexbin, and the associated
+hexplot. The extensions discussed in this section will be smoothing
+hexbin objects using the hsmooth function, approximating a bivariate
+median with hexagons and a version of a bivariate boxplot, and using
+eroded hexbin objects to look at the overlap of two bivariate populations.
+
+\subsection{Smoothing with \texttt{hsmooth}}
+At this point the hexbin package only provides a single option for
+smoothing using a discrete kernel. Several improvements are in
+development including an apply function over neighborhoods and spline
+functions using a hexagonal basis or tensor products. The apply
+function should facilitate constructing more sophisticated kernel
+smoothers. The hexagon splines will provide an alternative to
+smoothing on a square grid and allow interpolation of hexagons to
+finer grids.
+
+The current implementation uses the center cell, immediate
+neighbors and second neighbors to smooth the counts. The counts for
+each resulting cell is a linear combination of the counts in the
+defined neighborhood, including the center cell and weights. The
+counts are blurred over the the domain, and the domain increases
+because of shifting. Generally the dimension of the occupied cells of
+the lattice increases by one, sometimes two.
+
+Some examples of using the hsmooth function are given below. Notice in
+the plots that the first plot is with no smoothing, weights are
+\texttt{c(1,0,0)} meaning that only the center cell is used with
+identity weights. The second plot shows a first order kernel using
+weights \texttt{c(24,12,0)}, while the third plot uses weights for
+first and second order neighbors specified as \texttt{c(48,24,12)}.
+The code segment generating these plots rescales the smoothed counts
+so that they are on the original scale.
+
+<< showsmth, fig = TRUE, width = 8, height = 4, echo = FALSE >>=
+#nf <- layout(matrix(c(1,1,2,2,4,3,3,4), ncol=4, nrow=2, byrow=TRUE),
+# widths = rep(1,4), heights=rep(1,2))
+x <- rnorm(10000)
+y <- rnorm(10000)
+grid.newpage()
+mar <- unit(0.1 + c(5,4,4,2),"lines")
+mai <- as.numeric(convertUnit(mar, "inches"))
+vpin <- c(convertWidth (unit(1,"npc"), "inches"),
+ convertHeight(unit(1,"npc"), "inches"))
+shape <- optShape(height = vpin[2],width = vpin[1]/3,mar = mai)
+hbin <- hexbin(x,y, xbins = 30,shape = shape)
+hsmbin1 <- hsmooth(hbin, c( 1, 0,0))
+hsmbin2 <- hsmooth(hbin, c(24,12,0))
+hsmbin2 at count <- as.integer(ceiling(hsmbin2 at count/sum(hsmbin2 at wts)))
+hsmbin3 <- hsmooth(hbin,c(48,24,12))
+hsmbin3 at count <- as.integer(ceiling(hsmbin3 at count/sum(hsmbin3 at wts)))
+pushViewport(viewport(layout = grid.layout(1, 3)))
+pushViewport(viewport(layout.pos.col = 1, layout.pos.row = 1))
+plot(hsmbin1, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY)
+popViewport()
+pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1))
+plot(hsmbin2, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY)
+popViewport()
+pushViewport(viewport(layout.pos.col = 3,layout.pos.row = 1))
+plot(hsmbin3, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY)
+popViewport()
+@
+\subsection{Bin Erosion and the \texttt{hboxplot}}
+The next tool to introduce, gray level erosion, extends the idea of
+the boxplot. The idea is to extract cells in a way that the most
+exposed cells are removed first, ie cells with fewer neighbors, but
+cells with lower counts are removed preferentially to cells with
+higher counts. The algorithm works as follows:
+Mark the high count cells containing a given fraction, cdfcut, of
+the total counts. Mark all the cells if cdfcut is zero.
+The algorithm then performs gray-level erosion on the
+marked cells. Each erosion cycle removes counts from cells. The
+counts removed from each cell are a multiple of the cell's exposed-face
+count. The algorithm chooses the multiple so at least one cell will be
+empty or have a count deficit on each erosion cycle. The erode vector
+contains an erosion number for each cell. The value of erode is
+
+\begin{center}
+ $6\times$(The erosion cycle at cell removal) $ - $
+ (The cell deficit at removal)
+\end{center}
+
+The cell with the highest erosion number is a candidate bivariate
+median. A few ties in the erosion order are common.
+
+The notion of an ordering to the median is nice because it allows us
+to create a version of a bivariate box plot built on hexagons. The
+following example comes from a portion of the ''National Health and Nutrition
+Examination Survey'' included in \texttt{hexbin} as the sample data
+set NHANES. The data consist of 9575 persons and mesures various
+clinical factors. Here in Figure~\ref{hbox} we show the levels of
+transferin, a measure of iron binding against hemoglobin for all
+
+\begin{figure}[h]
+ \centering
+
+<< echo = FALSE >>=
+data(NHANES)
+#grid.newpage()
+mar <- unit(0.1 + c(5,4,4,2),"lines")
+mai <- as.numeric(convertUnit(mar, "inches"))
+#vpin <- c(convertWidth (unit(1,"npc"), "inches"),
+# convertHeight(unit(1,"npc"), "inches"))
+vpin <- c(unit(6,"inches"),unit(4, "inches"))
+shape <- optShape(height = vpin[2], width = vpin[1], mar = mai)
+@
+
+<< hbox, fig = TRUE, width = 6, height = 4, echo = FALSE >>=
+hb <- hexbin(NHANES$Transferin, NHANES$Hemoglobin, shape = shape)
+hbhp <- hboxplot(erode(hb,cdfcut = .05),unzoom = 1.3)
+pushHexport(hbhp,clip = 'on')
+hexGraphPaper(hb,fill.edges = 3)
+popViewport()
+@
+\caption{Hexagon "boxplots" showing the top 95 percent of the data for
+ males and females. The red hexagons are an estimate of the bivariate median.}
+\label{hbox}
+\end{figure}
+
+Note that we have added ``hexagon graph paper'' to the plot. This can
+be done for any hexbin plot, using the command
+\texttt{hexGraphPaper()} where the main argument is the hexbin object.
+
+\subsection{Comparing Distributions and the \texttt{hdiffplot}}
+With univariate data, if there are multiple groups, one often uses a
+density estimate to overlay densities, and compare two or more
+distributions. The hdiffplot is the bivariate analog. The idea behind
+the hdiff plot is to plot one or more bin objects representing
+multiple groups to compare the distributions. The following example
+uses the National Health data supplied in the hexbin package,
+(\texttt{NHANES}). Below we show a comparison of males and females,
+the bivariate relationship is transferin, which is a derived measure
+of the ability of blood to bind oxygen, vs the level of hemoglobin.
+Note that in the call to \texttt{hdiffplot} we erode the bins to
+calculate the bivariate medians, and only display the upper 75\% of
+the data.
+\begin{figure}[h]
+ \centering
+<< hdiff, fig = TRUE, width = 6, height = 4, echo = TRUE >>=
+#grid.newpage()
+shape <- optShape(height = vpin[2],width = vpin[1],mar = mai)
+xbnds <- range(NHANES$Transferin,na.rm = TRUE)
+ybnds <- range(NHANES$Hemoglobin,na.rm = TRUE)
+hbF <- hexbin(NHANES$Transferin[NHANES$Sex == "F"],
+ NHANES$Hemoglobin[NHANES$Sex == "F"],
+ xbnds = xbnds, ybnds = ybnds, shape = shape)
+hbM <- hexbin(NHANES$Transferin[NHANES$Sex == "M"],
+ NHANES$Hemoglobin[NHANES$Sex == "M"],
+ xbnds = xbnds, ybnds = ybnds, shape = shape)
+#plot.new()
+hdiffplot(erode(hbF,cdfcut = .25),erode(hbM,cdfcut = .25),unzoom = 1.3)
+@
+\caption{A difference plot of transferin vs hemoglobin for males and females.}
+\label{hdiffplot}
+\end{figure}
+
+
+
+\subsection{Plotting a Third Concomitant Variable}
+In many cases, such as with spatial data, one may want to plot the
+levels of a third variable in each hexagon. The grid.hexagons function
+has a pair of arguments, \texttt{use.count} and \texttt{cell.at}. If
+\texttt{use.count = FALSE} and \texttt{cell.at} is a numeric vector of
+the same length as \texttt{hexbin at count} then the attribute vector
+will be used instead of the counts. \texttt{hexTapply} will
+summarize values for each hexagon according to the supplied function
+and return the table in the right order to use as an attribute
+vector. Another alternative is to set the \texttt{cAtt} slot of the
+hexbin object and grid.hexagons will automatically plot the attribute
+if \texttt{use.count = FALSE} and \texttt{cell.at = NULL}.
+
+Here is an example using spatial data. Often cartographers use
+graduated symbols to display varying numerical quantities across a region.
+
+
+
+\section{Example: cDNA Chip Normalization}
+This example is taken from the marray package, which
+supplies methods and classes for the normalization and diagnostic
+plots of cDNA microarrays. In this example the goal is not to make any
+comments about the normalization methodology, but rather to show how
+the diagnostic plots can be enhanced using hexagon binning due to the
+large number of points ($n = 8,448$ cDNA probes per chip).
+
+We look at the diagnostic plot $M$ vs $A$, where $M$ is the
+log--ratio, $M = \log <- 2 \frac{R}{G}$ and $A$ is the overall intensity,
+$A = \log <- 2\sqrt{RG}$. Figure~3 shows the plot using points and on the
+right hexagons. The hexagon binned plot shows that most of the pairs
+are well below zero, and that the overall shape is more like a comet
+with most of the mass at the bottom of the curve, rather than a thick
+bar of points curving below the line.
+
+<< marray1, fig = TRUE, results = hide >>=
+### Need to redo this part.
+library("marray")
+data(swirl, package = "marray") ## use swirl dataset
+
+hb1 <- hexbin(maA(swirl[,1]), maM(swirl[,1]), xbins = 40)
+grid.newpage()
+pushViewport(viewport(layout = grid.layout(1, 2)))
+
+pushViewport(viewport(layout.pos.col = 1,layout.pos.row = 1))
+nb <- plot(hb1, type = 'n', xlab = 'A', ylab = 'M',
+ main = "M vs A plot with points", legend = 0, newpage = FALSE)
+pushHexport(nb$plot.vp)
+grid.points(maA(swirl[,1]), maM(swirl[,1]),pch = 16,gp = gpar(cex = .4))
+popViewport()
+nb$hbin <- hb1
+hexVP.abline(nb$plot.vp,h = 0,col = gray(.6))
+hexMA.loess(nb)
+popViewport()
+
+pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1))
+hb <- plotMAhex(swirl[,1], newpage = FALSE,
+ main = "M vs A plot with hexagons", legend = 0)
+hexVP.abline(hb$plot.vp,h = 0,col = gray(.6))
+hexMA.loess(hb)
+popViewport()
+@
+
+
+
+\section{Manipulating Hexbins}
+The underlying functions for hexbin have been rewritten and now depend
+on the grid graphics system. The support unit for all hexagon plots is
+the hexViewport. The function \texttt{hexViewport()} takes a hexbin
+object as input and creates a viewport scaled to the current device or
+viewport so that the aspect ratio is scaled appropriately for the
+hexagons. Unlike in the base graphic functions where the aspect ratio
+is maintained by shifting the range of the axes, here the extra space
+is shifted into the margins. Currently hexViewport returns a
+hexViewport object that has information on the margins and
+its own pushViewport method. In the next example we will 1st show how
+to manipulate an existing plot using grid commands and second show how to
+create a custom plotting function using \texttt{hexViewport} and grid.
+
+\subsection{Adding to an existing plot}
+Adding to an existing plot requires the use of grid
+functions. For instance, in the following code,
+<< addto,fig = TRUE,echo = TRUE >>=
+hplt <- plot(hb1,style = 'centroid',border = gray(.65))
+pushHexport(hplt$plot.vp)
+ll.fit <- loess(hb1 at ycm ~ hb1 at xcm, weights = hb1 at count, span = .4)
+pseq <- seq(hb1 at xbnds[1]+1, hb1 at xbnds[2]-1, length = 100)
+grid.lines(pseq, predict(ll.fit,pseq),
+ gp = gpar(col = 2), default.units = "native")
+@
+we have to use \texttt{grid.lines()}, as opposed to \texttt{lines()}.
+
+
+\end{document}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/r-cran-hexbin.git
More information about the debian-med-commit
mailing list