scattermore/0000755000176200001440000000000014202426322012577 5ustar liggesusersscattermore/NAMESPACE0000644000176200001440000000114214202422745014021 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(geom_scattermore) export(geom_scattermost) export(scattermore) export(scattermoreplot) importFrom(ggplot2,Geom) importFrom(ggplot2,aes) importFrom(ggplot2,aes_string) importFrom(ggplot2,draw_key_point) importFrom(ggplot2,ggproto) importFrom(ggplot2,layer) importFrom(grDevices,as.raster) importFrom(grDevices,col2rgb) importFrom(grDevices,dev.size) importFrom(grDevices,rgb) importFrom(graphics,par) importFrom(graphics,plot) importFrom(graphics,rasterImage) importFrom(grid,rasterGrob) importFrom(scales,alpha) useDynLib(scattermore, .registration = TRUE) scattermore/man/0000755000176200001440000000000014202422745013357 5ustar liggesusersscattermore/man/scattermore.Rd0000644000176200001440000000270414202422745016201 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/scattermore.R \name{scattermore} \alias{scattermore} \title{scattermore} \usage{ scattermore( xy, size = c(512, 512), xlim = c(min(xy[, 1]), max(xy[, 1])), ylim = c(min(xy[, 2]), max(xy[, 2])), rgba = c(0L, 0L, 0L, 255L), cex = 0, output.raster = TRUE ) } \arguments{ \item{xy}{2-column float matrix with point coordinates. As usual with rasters in R, X axis grows right, and Y axis grows DOWN. Flipping \code{ylim} causes the usual mathematical behavior.} \item{size}{2-element vector integer size of the result raster, defaults to \code{c(512,512)}.} \item{xlim, ylim}{Float limits as usual (position of the first pixel on the left/top, and the last pixel on the right/bottom). You can easily flip the top/bottom to the "usual" mathematical system by flipping the \code{ylim} vector.} \item{rgba}{4-row matrix with color values of 0-255, or just a single 4-item vector for \code{c(r,g,b,a)}. Best created with \code{col2rgb(..., alpha=TRUE)}.} \item{cex}{Additional point radius in pixels, 0=single-pixel dots (fastest)} \item{output.raster}{Output R-style raster (as.raster)? Default TRUE. Raw array output can be used much faster, e.g. for use with png::writePNG.} } \value{ Raster with the result. } \description{ Convert points to raster scatterplot rather quickly. } \examples{ library(scattermore) plot(scattermore(cbind(rnorm(1e6),rnorm(1e6)), rgba=c(64,128,192,10))) } scattermore/man/geom_scattermost.Rd0000644000176200001440000000263714202422745017235 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/scattermore.R \name{geom_scattermost} \alias{geom_scattermost} \title{geom_scattermost} \usage{ geom_scattermost( xy, color = "black", interpolate = FALSE, pointsize = 0, pixels = c(512, 512) ) } \arguments{ \item{xy}{2-column object with data, as in \code{\link[=scattermore]{scattermore()}}.} \item{color}{Color vector (or a single color).} \item{interpolate}{Default FALSE, passed to \code{\link[grid:grid.raster]{grid::rasterGrob()}}.} \item{pointsize}{Radius of rasterized point. Use \code{0} for single pixels (fastest).} \item{pixels}{Vector with X and Y resolution of the raster, default \code{c(512,512)}.} } \description{ Totally non-ggplotish version of \code{\link[=geom_scattermore]{geom_scattermore()}}, but faster. It avoids most of the ggplot processing by bypassing the largest portion of data around any ggplot functionality, leaving only enough data to set up axes and limits correctly. If you need to break speed records, use this. } \examples{ library(ggplot2) library(scattermore) d <- data.frame(x=rnorm(1000000), y=rnorm(1000000)) x_rng <- range(d$x) ggplot() + geom_scattermost(cbind(d$x,d$y), color=heat.colors(100, alpha=.01) [1+99*(d$x-x_rng[1])/diff(x_rng)], pointsize=2.5, pixels=c(1000,1000), interpolate=TRUE) } scattermore/man/scattermoreplot.Rd0000644000176200001440000000237314202422745017102 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/scattermore.R \name{scattermoreplot} \alias{scattermoreplot} \title{scattermoreplot} \usage{ scattermoreplot( x, y, xlim, ylim, size, col = grDevices::rgb(0, 0, 0, 1), cex = 0, pch = NULL, xlab, ylab, ... ) } \arguments{ \item{x, y, xlim, ylim, xlab, ylab, ...}{used as in \code{\link[graphics:plot.default]{graphics::plot()}} or forwarded to \code{\link[graphics:plot.default]{graphics::plot()}}} \item{size}{forwarded to \code{\link[=scattermore]{scattermore()}}, or auto-derived from device and plot size if missing (the estimate is not pixel-perfect on most devices, but gets pretty close)} \item{col}{point color(s)} \item{cex}{forwarded to \code{\link[=scattermore]{scattermore()}}} \item{pch}{ignored (to improve compatibility with \code{\link[graphics:plot.default]{graphics::plot()}}} } \description{ Convenience base-graphics-like layer around scattermore. Currently only works with linear axes! } \examples{ # plot an actual rainbow library(scattermore) d <- data.frame(s=qlogis(1:1e6/(1e6+1), 6, 0.5), t=rnorm(1e6, pi/2, 0.5)) scattermoreplot( d$s*cos(d$t), d$s*sin(d$t), col=rainbow(1e6, alpha=.05)[c((9e5+1):1e6, 1:9e5)], main="scattermore demo") } scattermore/man/geom_scattermore.Rd0000644000176200001440000000355414202422745017214 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/scattermore.R \name{geom_scattermore} \alias{geom_scattermore} \title{geom_scattermore} \usage{ geom_scattermore( mapping = NULL, data = NULL, stat = "identity", position = "identity", ..., na.rm = FALSE, show.legend = NA, inherit.aes = TRUE, interpolate = FALSE, pointsize = 0, pixels = c(512, 512) ) } \arguments{ \item{mapping, data, stat, position, inherit.aes, show.legend, ...}{passed to \code{\link[ggplot2:layer]{ggplot2::layer()}}} \item{na.rm}{Remove NA values, just as with \code{\link[ggplot2:geom_point]{ggplot2::geom_point()}}.} \item{interpolate}{Default FALSE, passed to \code{\link[grid:grid.raster]{grid::rasterGrob()}}.} \item{pointsize}{Radius of rasterized point. Use \code{0} for single pixels (fastest).} \item{pixels}{Vector with X and Y resolution of the raster, default \code{c(512,512)}.} } \description{ \code{\link[ggplot2:ggplot]{ggplot2::ggplot()}} integration. This cooperates with the rest of ggplot (so you can use it to e.g. add rasterized scatterplots to vector output in order to reduce PDF size). Note that the ggplot processing overhead still dominates the plotting time. Use \code{\link[=geom_scattermost]{geom_scattermost()}} to tradeoff some niceness and circumvent ggplot logic to gain speed. } \details{ Accepts aesthetics \code{x}, \code{y}, \code{colour} and \code{alpha}. Point size is fixed for all points. Due to rasterization properties it is often beneficial to try non-integer point sizes, e.g. \code{3.2} looks much better than \code{3}. } \examples{ library(ggplot2) library(scattermore) ggplot(data.frame(x=rnorm(1e6), y=rexp(1e6))) + geom_scattermore(aes(x,y,color=x), pointsize=3, alpha=0.1, pixels=c(1000,1000), interpolate=TRUE) + scale_color_viridis_c() } scattermore/DESCRIPTION0000644000176200001440000000144714202426322014313 0ustar liggesusersPackage: scattermore Title: Scatterplots with More Points Version: 0.8 Authors@R: person(given = "Mirek", family = "Kratochvil", role = c("aut", "cre"), email = "exa.exa@gmail.com", comment = c(ORCID = "0000-0001-7356-4075")) Description: C-based conversion of large scatterplot data to rasters. Speeds up plotting of data with millions of points. URL: https://github.com/exaexa/scattermore Imports: ggplot2, scales, grid, grDevices, graphics License: GPL (>= 3) Encoding: UTF-8 RoxygenNote: 7.1.1 NeedsCompilation: yes Packaged: 2022-02-14 09:50:56 UTC; exa Author: Mirek Kratochvil [aut, cre] () Maintainer: Mirek Kratochvil Repository: CRAN Date/Publication: 2022-02-14 10:20:02 UTC scattermore/src/0000755000176200001440000000000014202422745013373 5ustar liggesusersscattermore/src/scattermore.c0000644000176200001440000001372714202422745016101 0ustar liggesusers /* This file is part of scattermore. * * Copyright (C) 2019-2020 Mirek Kratochvil * * scattermore 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 3 of the License, or (at your option) * any later version. * * scattermore 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 * scattermore. If not, see . * * ----- * * format this file with: * clang-format-7 -style="{BasedOnStyle: Mozilla, UseTab: ForIndentation, IndentWidth: 8, TabWidth: 8}" */ #include #include #include void scattermore(const int *pn, const int *pncol, const int *size, const float *xlim, const float *ylim, const float *pcex, const float *xy, const unsigned *rgba, unsigned *rd) { const size_t n = *pn, ncol = *pncol, sizex = size[0], sizey = size[1], sizexy = sizex * sizey, offg = sizexy, offb = offg * 2, offa = offg * 3; const float xb = xlim[0], xe = xlim[1], xips = (sizex - 1) / (xe - xb), yb = ylim[1], ye = ylim[0], yips = (sizey - 1) / (ye - yb), cex = *pcex; size_t i; for (i = 0; i < sizexy * 4; ++i) rd[i] = 0; if (cex < 0.000000001) { // epsilol if (ncol == 1) { #define get_color(ii) \ unsigned sa = rgba[ii * 4 + 3] * 128, \ sr = rgba[ii * 4 + 0] * sa / 255, \ sg = rgba[ii * 4 + 1] * sa / 255, \ sb = rgba[ii * 4 + 2] * sa / 255; get_color(0); for (i = 0; i < n; ++i) { #define get_xy \ const unsigned x = (xy[i] - xb) * xips, y = (xy[i + n] - yb) * yips; \ if (x >= sizex || y >= sizey) \ continue; get_xy; #define paint_point \ const size_t off = y + sizey * x; \ const unsigned dr = rd[off], dg = rd[off + offg], db = rd[off + offb], \ da = rd[off + offa]; \ \ rd[off] = sr + dr - ((sa * dr) / 32640); \ rd[off + offg] = sg + dg - ((sa * dg) / 32640); \ rd[off + offb] = sb + db - ((sa * db) / 32640); \ rd[off + offa] = sa + da - ((sa * da) / 32640); #define paint_point_vars(sr, sg, sb, sa) \ const size_t off = y + sizey * x; \ const unsigned dr = rd[off], dg = rd[off + offg], db = rd[off + offb], \ da = rd[off + offa]; \ \ rd[off] = sr + dr - ((sa * dr) / 32640); \ rd[off + offg] = sg + dg - ((sa * dg) / 32640); \ rd[off + offb] = sb + db - ((sa * db) / 32640); \ rd[off + offa] = sa + da - ((sa * da) / 32640); paint_point; } } else { for (i = 0; i < n; ++i) { get_color(i); get_xy; paint_point; } } } else { const int cr = ceilf(cex) + 1, crsq = cex * cex, crsq1 = (cex + 1) * (cex + 1), crsqd = crsq1 - crsq; if (ncol == 1) { get_color(0); for (i = 0; i < n; ++i) { #define paint_circle \ const int cx = (xy[i] - xb) * xips, cy = (xy[i + n] - yb) * yips, \ pxb = cx <= cr ? 0 : cx - cr, \ pxe = cx + cr + 1 >= (int)sizex ? (int)sizex : cx + cr + 1, \ pyb = cy <= cr ? 0 : cy - cr, \ pye = cy + cr + 1 >= (int)sizey ? (int)sizey : cy + cr + 1; \ \ int x, y; \ for (x = pxb; x < pxe; ++x) \ for (y = pyb; y < pye; ++y) { \ int tmp = (x - cx) * (x - cx) + (y - cy) * (y - cy); \ if (tmp > crsq1) \ continue; \ if (tmp < crsq) { \ paint_point; \ continue; \ } \ tmp = crsq1 - tmp; \ const unsigned nsa = sa * tmp / crsqd; \ paint_point_vars((sr * tmp / crsqd), \ (sg * tmp / crsqd), \ (sb * tmp / crsqd), \ nsa); \ } paint_circle; } } else { for (i = 0; i < n; ++i) { get_color(i); paint_circle; } } } // un-premultiply alpha for (i = 0; i < sizexy; ++i) { if (!rd[i + offa]) continue; rd[i] = (rd[i] * 255) / rd[i + offa]; rd[i + offg] = (rd[i + offg] * 255) / rd[i + offa]; rd[i + offb] = (rd[i + offb] * 255) / rd[i + offa]; rd[i + offa] /= 128; } } static const R_CMethodDef cMethods[] = { { "scattermore", (DL_FUNC)&scattermore, 9 }, { NULL, NULL, 0 } }; void R_init_Scattermore(DllInfo *info) { R_registerRoutines(info, cMethods, NULL, NULL, NULL); R_useDynamicSymbols(info, FALSE); } scattermore/R/0000755000176200001440000000000014202422745013005 5ustar liggesusersscattermore/R/scattermore.R0000644000176200001440000002516414202422745015470 0ustar liggesusers# This file is part of scattermore. # # Copyright (C) 2019-2020 Mirek Kratochvil # # scattermore 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 3 of the License, or # (at your option) any later version. # # scattermore 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 scattermore. If not, see . #' scattermore #' #' Convert points to raster scatterplot rather quickly. #' #' @param xy 2-column float matrix with point coordinates. As usual with #' rasters in R, X axis grows right, and Y axis grows DOWN. #' Flipping `ylim` causes the usual mathematical behavior. #' @param size 2-element vector integer size of the result raster, #' defaults to `c(512,512)`. #' @param xlim,ylim Float limits as usual (position of the first pixel on the #' left/top, and the last pixel on the right/bottom). You can #' easily flip the top/bottom to the "usual" mathematical #' system by flipping the `ylim` vector. #' @param rgba 4-row matrix with color values of 0-255, or just a single 4-item #' vector for `c(r,g,b,a)`. Best created with `col2rgb(..., alpha=TRUE)`. #' @param cex Additional point radius in pixels, 0=single-pixel dots (fastest) #' @param output.raster Output R-style raster (as.raster)? Default TRUE. Raw #' array output can be used much faster, #' e.g. for use with png::writePNG. #' @return Raster with the result. #' #' @useDynLib scattermore, .registration = TRUE #' @examples #' library(scattermore) #' plot(scattermore(cbind(rnorm(1e6),rnorm(1e6)), rgba=c(64,128,192,10))) #' @export #' @importFrom grDevices as.raster scattermore <- function( xy, size=c(512,512), xlim=c(min(xy[,1]),max(xy[,1])), ylim=c(min(xy[,2]),max(xy[,2])), rgba=c(0L,0L,0L,255L), cex=0, output.raster=TRUE) { n <- dim(xy)[1] if(dim(xy)[2] != 2) stop('2-column xy input expected') col <- if(is.matrix(rgba)) as.integer(rgba) else rgba ncol <- length(col) if(!(ncol %in% (4*c(1,n)))) stop('unsupported rgba content') ncol <- ncol %/% 4L rd <- rep(0L,size[1]*size[2]*4) res <- .C("scattermore", n=as.integer(n), ncol=as.integer(ncol), size=as.integer(size), xlim=as.single(xlim), ylim=as.single(ylim), cex=as.single(cex), xy=as.single(xy), rgba=as.integer(rgba), rd=as.integer(rd)) if(output.raster) grDevices::as.raster(array(res$rd,c(size[2],size[1],4)), max=255L) else array(res$rd,c(size[2],size[1],4)) } #' scattermoreplot #' #' Convenience base-graphics-like layer around scattermore. Currently only works with linear axes! #' #' @param x,y,xlim,ylim,xlab,ylab,... used as in [graphics::plot()] or forwarded to [graphics::plot()] #' @param col point color(s) #' @param cex forwarded to [scattermore()] #' @param pch ignored (to improve compatibility with [graphics::plot()] #' @param size forwarded to [scattermore()], or auto-derived from device and plot size if missing (the estimate is not pixel-perfect on most devices, but gets pretty close) #' @examples #' # plot an actual rainbow #' library(scattermore) #' d <- data.frame(s=qlogis(1:1e6/(1e6+1), 6, 0.5), t=rnorm(1e6, pi/2, 0.5)) #' scattermoreplot( #' d$s*cos(d$t), #' d$s*sin(d$t), #' col=rainbow(1e6, alpha=.05)[c((9e5+1):1e6, 1:9e5)], #' main="scattermore demo") #' @export #' @importFrom graphics par #' @importFrom graphics plot #' @importFrom graphics rasterImage #' @importFrom grDevices dev.size #' @importFrom grDevices rgb scattermoreplot <- function( x, y, xlim, ylim, size, col=grDevices::rgb(0,0,0,1), cex=0, pch=NULL, xlab, ylab, ...) { if(missing(x)) stop("Supply at least one vector for plotting") if(!missing(y)) x <- cbind(x,y) if(missing(xlim)) xlim <- c(min(x[,1]),max(x[,1])) if(missing(ylim)) ylim <- c(min(x[,2]),max(x[,2])) xlab <- if(!missing(xlab)) xlab else if(!is.null(colnames(x))) colnames(x)[1] else "X" ylab <- if(!missing(ylab)) ylab else if(!is.null(colnames(x))) colnames(x)[2] else "Y" graphics::plot(x[1,], pch='', xlim=xlim, ylim=ylim, xlab=xlab, ylab=ylab, ...) usr <- graphics::par('usr') if(missing(size)) size <- as.integer( grDevices::dev.size('px') / grDevices::dev.size('in') * graphics::par('pin')) graphics::rasterImage( scattermore( x, size=size, xlim=usr[1:2], ylim=usr[3:4], cex=cex, rgba=grDevices::col2rgb(col, alpha=TRUE), output.raster=TRUE), xleft=usr[1], xright=usr[2], ybottom=usr[3], ytop=usr[4], ) } #' geom_scattermore #' #' [ggplot2::ggplot()] integration. This cooperates with the rest of ggplot #' (so you can use it to e.g. add rasterized scatterplots to vector output in #' order to reduce PDF size). Note that the ggplot processing overhead still dominates #' the plotting time. Use [geom_scattermost()] to tradeoff some niceness and #' circumvent ggplot logic to gain speed. #' #' Accepts aesthetics `x`, `y`, `colour` and `alpha`. Point size is fixed for #' all points. Due to rasterization properties it is often beneficial to try #' non-integer point sizes, e.g. `3.2` looks much better than `3`. #' #' @param na.rm Remove NA values, just as with [ggplot2::geom_point()]. #' @param interpolate Default FALSE, passed to [grid::rasterGrob()]. #' @param pointsize Radius of rasterized point. Use `0` for single pixels (fastest). #' @param pixels Vector with X and Y resolution of the raster, default `c(512,512)`. #' @param mapping,data,stat,position,inherit.aes,show.legend,... passed to [ggplot2::layer()] #' @examples #' library(ggplot2) #' library(scattermore) #' ggplot(data.frame(x=rnorm(1e6), y=rexp(1e6))) + #' geom_scattermore(aes(x,y,color=x), #' pointsize=3, #' alpha=0.1, #' pixels=c(1000,1000), #' interpolate=TRUE) + #' scale_color_viridis_c() #' @export #' @importFrom ggplot2 layer geom_scattermore <- function( mapping=NULL, data=NULL, stat="identity", position="identity", ..., na.rm=FALSE, show.legend = NA, inherit.aes = TRUE, interpolate = FALSE, pointsize = 0, pixels=c(512,512)) { ggplot2::layer( data = data, mapping = mapping, stat = stat, position = position, geom = GeomScattermore, show.legend = show.legend, inherit.aes = inherit.aes, params = list( na.rm = na.rm, interpolate = interpolate, pointsize = pointsize, pixels=pixels, ... ) ) } #' The actual geom for scattermore #' #' @importFrom ggplot2 aes #' @importFrom ggplot2 draw_key_point #' @importFrom ggplot2 Geom #' @importFrom ggplot2 ggproto #' @importFrom grDevices col2rgb #' @importFrom grid rasterGrob #' @importFrom scales alpha GeomScattermore <- ggplot2::ggproto("GeomScattermore", ggplot2::Geom, required_aes = c("x", "y"), non_missing_aes = c("alpha", "colour"), default_aes = ggplot2::aes( shape = 19, colour = "black", size = 1.5, fill = NA, alpha = 1, stroke = 0.5 ), draw_panel = function(data, pp, coord, pointsize = 0, interpolate = F, na.rm = FALSE, pixels=c(512,512)) { coords <- coord$transform(data, pp) ggplot2:::ggname("geom_scattermore", grid::rasterGrob( scattermore( cbind(coords$x, coords$y), rgba=grDevices::col2rgb(alpha=TRUE, scales::alpha(coords$colour, coords$alpha)), cex=pointsize, xlim=c(0,1), ylim=c(0,1), size=pixels ), 0,0,1,1, default.units='native', just=c('left','bottom'), interpolate=interpolate ) ) }, draw_key = ggplot2::draw_key_point ) #' geom_scattermost #' #' Totally non-ggplotish version of [geom_scattermore()], but faster. It avoids #' most of the ggplot processing by bypassing the largest portion of data #' around any ggplot functionality, leaving only enough data to set up axes and #' limits correctly. If you need to break speed records, use this. #' #' @param xy 2-column object with data, as in [scattermore()]. #' @param color Color vector (or a single color). #' @param interpolate Default FALSE, passed to [grid::rasterGrob()]. #' @param pointsize Radius of rasterized point. Use `0` for single pixels (fastest). #' @param pixels Vector with X and Y resolution of the raster, default `c(512,512)`. #' @examples #' library(ggplot2) #' library(scattermore) #' d <- data.frame(x=rnorm(1000000), y=rnorm(1000000)) #' x_rng <- range(d$x) #' ggplot() + #' geom_scattermost(cbind(d$x,d$y), #' color=heat.colors(100, alpha=.01) #' [1+99*(d$x-x_rng[1])/diff(x_rng)], #' pointsize=2.5, #' pixels=c(1000,1000), #' interpolate=TRUE) #' @export #' @importFrom ggplot2 aes_string #' @importFrom ggplot2 layer geom_scattermost <- function( xy, color = "black", interpolate = FALSE, pointsize = 0, pixels=c(512,512)) { ggplot2::layer( data = data.frame(x=c(min(xy[,1]),max(xy[,1])), y=c(min(xy[,2]),max(xy[,2]))), mapping = ggplot2::aes_string(x="x",y="y"), stat = 'identity', position = 'identity', geom = GeomScattermost, show.legend = NA, params = list( interpolate = interpolate, pointsize = pointsize, xy = xy, co = color, pixels=pixels ) ) } #' The actual geom for scattermost #' #' @importFrom ggplot2 draw_key_point #' @importFrom ggplot2 Geom #' @importFrom ggplot2 ggproto #' @importFrom grDevices col2rgb #' @importFrom grid rasterGrob GeomScattermost <- ggplot2::ggproto("GeomScattermost", ggplot2::Geom, required_aes = c("x", "y"), draw_panel = function(data, pp, coord, pointsize = 0, interpolate = F, xy, co="black", pixels=c(512,512)) { coords <- coord$transform(data.frame(x=xy[,1],y=xy[,2]),pp) ggplot2:::ggname("geom_scattermost", grid::rasterGrob( scattermore(cbind(coords$x, coords$y), cex=pointsize, rgba=grDevices::col2rgb(alpha=TRUE, co), xlim=c(0,1), ylim=c(0,1), size=pixels ), 0,0,1,1, default.units='native', just=c('left','bottom'), interpolate=interpolate ) ) }, draw_key = ggplot2::draw_key_point ) scattermore/MD50000644000176200001440000000064214202426322013111 0ustar liggesuserse0b5618640fe01be3e2b23c16b5f7db1 *DESCRIPTION 77576a692dd14aa00bb71e0ba4fa764a *NAMESPACE 08d4147c34c1b7a820dca4132dd8c37c *R/scattermore.R d527315c0131c678ab5d155ce9643c33 *man/geom_scattermore.Rd 5b78e6854fb7cb8a3c4d50bed313f83c *man/geom_scattermost.Rd 841b6168a04bd0e8999e5c3629078d25 *man/scattermore.Rd c1db6db163f7d25606995109e01f8976 *man/scattermoreplot.Rd 98f9a95552a11710fec935643c891c65 *src/scattermore.c