diff --git a/.Rbuildignore b/.Rbuildignore index 0c889a0..a4607f2 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -5,3 +5,4 @@ .gitignore .travis.yml _pkgdown.yml +codecov.yml diff --git a/.Rproj.user/84277BCC/sources/prop/INDEX b/.Rproj.user/84277BCC/sources/prop/INDEX index 153f2f6..4fff322 100644 --- a/.Rproj.user/84277BCC/sources/prop/INDEX +++ b/.Rproj.user/84277BCC/sources/prop/INDEX @@ -3,6 +3,7 @@ C%3A%2FUsers%2FZehao%2FDesktop%2FdatashadeR%2Fapp.R="D62258AD" C%3A%2FUsers%2FZehao%2FDesktop%2FdatashadeR%2Fnew_app.R="4D4286E2" C%3A%2FUsers%2FZehao%2FDesktop%2FdatashadeR%2Frasterizer%2FR%2Fplotly_rasterizer.R="9B582184" C%3A%2FUsers%2FZehao%2FDesktop%2FdatashadeR%2Ftime.R="3E5BAB2D" +C%3A%2FUsers%2FZehao%2FDesktop%2Fplotly%2FdatashadeR%2Ftime.R="272E2EC2" C%3A%2FUsers%2FZehao%2FDesktop%2Funtitled.Rmd="4192FD99" C%3A%2Frsa.pub="2A39FFB6" ~%2FGitHub%2FDocuments.pub="C29300F9" @@ -66,11 +67,28 @@ C%3A%2Frsa.pub="2A39FFB6" ~%2FGitHub%2Frasterly%2FDESCRIPTION="74BE175A" ~%2FGitHub%2Frasterly%2FNAMESPACE="1DD17E96" ~%2FGitHub%2Frasterly%2FR%2F_pkgdown.yml="59F334FE" +~%2FGitHub%2Frasterly%2FR%2Fadd_rasterly.R="CEDCD63B" +~%2FGitHub%2Frasterly%2FR%2Fadd_rasterly_heatmap.R="39EA1427" +~%2FGitHub%2Frasterly%2FR%2Fget_aesthetics.R="6B789F2F" +~%2FGitHub%2Frasterly%2FR%2FggRasterizer.R="95867414" ~%2FGitHub%2Frasterly%2FR%2Fplotly_rasterizer.R="95A84FE4" ~%2FGitHub%2Frasterly%2FR%2Fplotly_rasterly.R="18228E5F" +~%2FGitHub%2Frasterly%2FR%2Frasterize_points.R="2E260DA6" +~%2FGitHub%2Frasterly%2FR%2Frasterly-package.R="BFCA8213" +~%2FGitHub%2Frasterly%2FR%2Frasterly.R="A9996F87" +~%2FGitHub%2Frasterly%2FR%2Frasterly_build.R="7A3C86EA" +~%2FGitHub%2Frasterly%2FR%2Freexports.R="D1B1BBF4" ~%2FGitHub%2Frasterly%2FR%2Futils.R="8D9EEBAB" ~%2FGitHub%2Frasterly%2FREADME.md="9F226BD0" ~%2FGitHub%2Frasterly%2F_pkgdown.yml="BAE60E1" +~%2FGitHub%2Frasterly%2Fcodecov.yml="B207F478" +~%2FGitHub%2Frasterly%2Fdoc%2Fintroduction.R="5E09A20A" +~%2FGitHub%2Frasterly%2Fdoc%2Fintroduction.Rmd="E83AB2D" +~%2FGitHub%2Frasterly%2Fdoc%2Fintroduction.html="A1AC1F18" +~%2FGitHub%2Frasterly%2Fman%2Fadd_rasterly.Rd="BB1B2B04" +~%2FGitHub%2Frasterly%2Fman%2Frasterly-package.Rd="4C8DB46B" +~%2FGitHub%2Frasterly%2Fman%2Frasterly.Rd="2FDA8D7B" +~%2FGitHub%2Frasterly%2Ftests%2Ftestthat%2Ftest_rasterizer.R="59F3C36" ~%2FGitHub%2Frasterly%2Ftests%2Ftestthat.R="7976063B" ~%2FGitHub%2Frasterly%2Fvignettes%2Fintroduction.Rmd="2F40B97A" ~%2FGitHub%2Frsa.pub="8898C4BE" diff --git a/.travis.yml b/.travis.yml index 5761a48..0f79963 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,9 @@ addons: sudo: false language: r +r_github_packages: + - r-lib/covr + before_install: - export DISPLAY=':99.0' - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & @@ -22,4 +25,7 @@ cache: packages r: - release - - devel \ No newline at end of file + - devel + +after_success: + - Rscript -e 'covr::codecov()' \ No newline at end of file diff --git a/DESCRIPTION b/DESCRIPTION index ccef0e6..bc069b4 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -33,8 +33,10 @@ Suggests: compiler, loon, purrr, + covr, testthat, knitr, + rmarkdown, lubridate LazyData: true RoxygenNote: 6.1.1 diff --git a/NAMESPACE b/NAMESPACE index bb74586..6d3a244 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -7,7 +7,7 @@ S3method(as.raster,rasterizeMatrix) S3method(print,rasterly) export("%<-%") export("%>%") -export(add_rasterly) +export(add_rasterly_heatmap) export(aes) export(fire) export(hourColors) @@ -20,7 +20,6 @@ export(viridis) import(Rcpp) import(methods) import(rlang) -importFrom(compiler,cmpfun) importFrom(data.table,data.table) importFrom(ggplot2,aes) importFrom(grDevices,as.raster) diff --git a/R/add_rasterly.R b/R/add_rasterly_heatmap.R similarity index 69% rename from R/add_rasterly.R rename to R/add_rasterly_heatmap.R index 6f3304c..35c0f57 100644 --- a/R/add_rasterly.R +++ b/R/add_rasterly_heatmap.R @@ -14,49 +14,50 @@ #' #' @examples #' \dontrun{ -#' library(rasterly) -#' if(requireNamespace("plotly") && requireNamespace("data.table")) { -#' # Load data -#' ridesRaw_1 <- "https://raw.githubusercontent.com/plotly/datasets/ -#' master/uber-rides-data1.csv" %>% -#' data.table::fread(stringsAsFactors = FALSE) -#' ridesRaw_2 <- "https://raw.githubusercontent.com/plotly/datasets/ -#' master/uber-rides-data2.csv" %>% -#' data.table::fread(stringsAsFactors = FALSE) -#' ridesRaw_3 <- "https://raw.githubusercontent.com/plotly/datasets/ -#' master/uber-rides-data3.csv" %>% -#' data.table::fread(stringsAsFactors = FALSE) -#' ridesDf <- list(ridesRaw_1, ridesRaw_2, ridesRaw_3) %>% -#' data.table::rbindlist() +#'library(rasterly) +#'if(requireNamespace("plotly") && requireNamespace("data.table")) { +#' # Load data +#' url1 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data1.csv" +#' ridesRaw_1 <- url1 %>% +#' data.table::fread(stringsAsFactors = FALSE) +#' url2 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data2.csv" +#' ridesRaw_2 <- url2 %>% +#' data.table::fread(stringsAsFactors = FALSE) +#' url3 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data3.csv" +#' ridesRaw_3 <- url3 %>% +#' data.table::fread(stringsAsFactors = FALSE) +#' +#' ridesDf <- list(ridesRaw_1, ridesRaw_2, ridesRaw_3) %>% +#' data.table::rbindlist() #' -#' #### quick start -#' p <- plot_ly(data = ridesDf) %>% -#' add_rasterly(x = ~Lat, y = ~Lon) -#' p -#' #### set artificial scaling function -#' zeroOneTransform <- function(z) { -#' minz <- min(z) -#' maxz <- max(z) -#' M <- matrix((z - minz)/(maxz - minz), nrow = dim(z)[1]) -#' return(M) -#' } -#' plot_ly(data = ridesDf) %>% -#' add_rasterly(x = ~Lat, -#' y = ~Lon, -#' on = ~-Lat, -#' reduction_func = "max", -#' scaling = zeroOneTransform) %>% -#' plotly::layout( -#' xaxis = list( -#' title = "x" -#' ), -#' yaxis = list( -#' title = "y" -#' ) -#' ) -#' } +#' #### quick start +#' p <- plot_ly(data = ridesDf) %>% +#' add_rasterly_heatmap(x = ~Lat, y = ~Lon) +#' p +#' #### set artificial scaling function +#' zeroOneTransform <- function(z) { +#' minz <- min(z) +#' maxz <- max(z) +#' M <- matrix((z - minz)/(maxz - minz), nrow = dim(z)[1]) +#' return(M) +#' } +#' plot_ly(data = ridesDf) %>% +#' add_rasterly_heatmap(x = ~Lat, +#' y = ~Lon, +#' on = ~-Lat, +#' reduction_func = "max", +#' scaling = zeroOneTransform) %>% +#' plotly::layout( +#' xaxis = list( +#' title = "x" +#' ), +#' yaxis = list( +#' title = "y" +#' ) +#' ) +#' } #' } -add_rasterly <- function(p, +add_rasterly_heatmap <- function(p, x = NULL, y = NULL, z = NULL, ..., data = NULL, inherit = TRUE, on = NULL, size = NULL, @@ -93,14 +94,16 @@ add_rasterly <- function(p, if(is.null(exp)) { mapping_names[i] <- NA } else { - if(rlang::is_expression(exp)) { + if(rlang::is_formula(exp)) { the_parse <- sub("~", "", rlang::expr_text(exp)) %>% rlang::parse_expr() mapping[[i]] <- rlang::quo(!!the_parse) } else if(is.numeric(exp)) { data[[mapping_names[i]]] <- exp mapping[[i]] <- rlang::quo(!!rlang::parse_expr(mapping_names[i])) - } else stop("'on' is neither `quote` nor a numerical value.", call. = FALSE) + } else { + stop("'size' ,'on' are neither `quote` nor a numerical value.", call. = FALSE) + } } } diff --git a/R/get_aesthetics.R b/R/get_aesthetics.R index 1769b08..fe599f5 100644 --- a/R/get_aesthetics.R +++ b/R/get_aesthetics.R @@ -56,14 +56,23 @@ get_aesthetics <- function(data = NULL, mapping = aes(), variable_check = FALSE, args <- list(...) abs_size <- args$size - max_size <- if(is.null(args$max_size)) 2 else args$max_size + max_size <- args$max_size %||% 2 if(!is.null(data$size) || !is.null(abs_size)) { if(is.null(abs_size)) { # standardized size - std <- function(size, max_size) {floor((size - min(size))/(max(size) - min(size)) * (max_size - 1))} - data[, size := std(data$size, max_size)] + std_size <- function(size, max_size) { + maxS <- max(size) + minS <- min(size) + if(maxS == minS) { + if(maxS < 1) stop("Pixel size cannot be less than one.") + floor(size) + } else { + floor((size - minS)/(maxS - minS) * (max_size - 1)) + } + } + data[, size := std_size(data$size, max_size)] } else { data[, size := abs_size] } diff --git a/R/ggRasterizer.R b/R/ggRasterizer.R index b6a6758..4bf46e5 100644 --- a/R/ggRasterizer.R +++ b/R/ggRasterizer.R @@ -1,34 +1,36 @@ ggRasterly <- function(data = NULL, - mapping = aes(), - ..., - plot_width = 600, plot_height = 600, - x_range = NULL, y_range = NULL, - background = "white", - color_map = c('lightblue','darkblue'), - color_key = NULL, - show_raster = TRUE, - drop_data = FALSE, - variable_check = FALSE) { + mapping = aes(), + ..., + plot_width = 600, plot_height = 600, + x_range = NULL, y_range = NULL, + background = "white", + color_map = c('lightblue','darkblue'), + color_key = NULL, + show_raster = TRUE, + drop_data = FALSE, + variable_check = FALSE) { rastObj <- rasterly(data = data, - mapping = mapping, - ..., - plot_width = plot_width, - plot_height = plot_height, - x_range = x_range, - y_range = y_range, - background = background, - color_map = color_map, - color_key = color_key, - show_raster = show_raster, - drop_data = drop_data, - variable_check = variable_check) %>% + mapping = mapping, + ..., + plot_width = plot_width, + plot_height = plot_height, + x_range = x_range, + y_range = y_range, + background = background, + color_map = color_map, + color_key = color_key, + show_raster = show_raster, + drop_data = drop_data, + variable_check = variable_check) %>% rasterize_points() %>% rasterly_build() + + len <- max(plot_width, plot_height) ggObj <- ggplot2::ggplot( - data = data.frame(x = seq(rastObj$x_range[1], rastObj$x_range[2], length.out = rastObj$plot_width), - y = seq(rastObj$y_range[1], rastObj$y_range[2], length.out = rastObj$plot_height)), + data = data.frame(x = seq(rastObj$x_range[1], rastObj$x_range[2], length.out = len), + y = seq(rastObj$y_range[1], rastObj$y_range[2], length.out = len)), mapping = aes(x = x, y = y) ) @@ -46,20 +48,9 @@ ggRasterly <- function(data = NULL, panel_line = theme$panel.grid$color %||% "white", background = rastObj$background) - - ggObj <- ggObj + - ggplot2::annotation_custom(grid::rasterGrob(image), - xmin = -Inf, xmax = Inf, - ymin = -Inf, ymax = Inf) + - ggplot2::theme( - axis.ticks = ggplot2::element_line(), - axis.text.x = ggplot2::element_text(), - axis.text.y = ggplot2::element_text(), - axis.title = ggplot2::element_text(), - axis.title.x = ggplot2::element_text(), - axis.title.y = ggplot2::element_text() - ) + ggplot2::annotation_custom(grid::rasterGrob(image)) + return(ggObj) } gg_pretty <- function(ggObj) { @@ -70,11 +61,11 @@ gg_pretty <- function(ggObj) { lapply(panel_params, function(panel_param) { list( - x_major = panel_param$x$breaks, - x_minor = panel_param$x$minor_breaks, + x_major = panel_param$x.major_source, + x_minor = panel_param$x.minor_source, x_range = panel_param$x.range, - y_major = panel_param$y$breaks, - y_minor = panel_param$y$minor_breaks, + y_major = panel_param$y.major_source, + y_minor = panel_param$y.minor_source, y_range = panel_param$y.range ) }) @@ -90,7 +81,7 @@ reset_image_bg <- function(image = NULL, background = "white") { if(is.null(image)) return(grid::rectGrob()) - + dimI <- dim(image) x_range <- x_range %||% c(1, dimI[2]) @@ -111,7 +102,7 @@ reset_image_bg <- function(image = NULL, image[image == background] <- panel_background image <- matrix(image, nrow = dimI[1]) - + for(x in x_pos) { column <- image[, x] column[column == panel_background] <- panel_line diff --git a/R/plotly_rasterly.R b/R/plotly_rasterly.R index 68f164b..64de225 100644 --- a/R/plotly_rasterly.R +++ b/R/plotly_rasterly.R @@ -1,7 +1,7 @@ #' @title `rasterly` to `plotly` #' @description Display raster image via `plotly` #' @param rastObj A rasterly object -#' @param as_heatmap Draw `plotly` by adding heatmap layer. See \code{add_rasterly} +#' @param as_heatmap Draw `plotly` by adding heatmap layer. See \code{add_rasterly_heatmap} #' @param scaling It could be an artificial function or a scaling way ("log", "origin") #' @param sizing Specifies which dimension of the image to constrain. One of "stretch" "fill", "contain" #' @param ... Arguments to the layout object. For documentation, diff --git a/R/rasterly-package.R b/R/rasterly-package.R index def93ca..e7fed3d 100644 --- a/R/rasterly-package.R +++ b/R/rasterly-package.R @@ -1,40 +1,20 @@ #' Easily and rapidly generate raster image data for large datasets using Plotly.js -#' @description Create a rasterly object, to which aggregation layers may be added. This function is the first step in the process -#' of generating raster image data using the `rasterly` package. -#' @param data Dataset to use for generating the plot. If not provided, data must be supplied in each layer of the plot. -#' For best performance, particularly when processing large datasets, use of \link[data.table]{data.table} is recommended. -#' @param mapping Default list of aesthetic mappings to use for plot. The same with `ggplot2` \link[ggplot2]{aes}. -#' See details. -#' @param ... Other arguments which will be passed through to layers. -#' @param plot_width Integer. The width of the image to plot; must be a positive integer. A higher value indicates a higher resolution. -#' @param plot_height Integer. The height of the image to plot; must be a positive integer. A higher value indicates a higher resolution. -#' @param x_range Vector of type numeric. The range of `x`; it can be used to clip the image. For larger datasets, providing `x_range` -#' may result in improved performance. -#' @param y_range Vector of type numeric. The range of `y`; it can be used to clip the image. For larger datasets, providing `y_range` -#' may result in improved performance. -#' @param background Character. The background color of the image to plot. -#' @param color_map Vector of type character. Color(s) used to draw each pixel. The `color_map` is extended by linear interpolation -#' independently for RGB. The darkness of the mapped color depends upon the values of the aggregation matrix. -#' @param color_key Vector of type character. The `color_key` is used for categorical variables; it is passed when the `color` aesthetic -#' is provided. -#' @param show_raster Logical. Should the raster be displayed? -#' @param drop_data Logical. When working with large datasets, drops the original data once processed according to the provided -#' `aes()` parameters, using the `remove()` function. See details for additional information. -#' @param variable_check Logical. If `TRUE`, drops unused columns to save memory; may result in reduced performance. +#' @description rasterly makes it easy to rapidly generate rasters in R, +#' even for very large datasets, with an aesthetics-based mapping syntax that +#' should be familiar to users of the \link{ggplot2} package. +#' While rasterly does not attempt to reproduce the full functionality of the +#' Datashader graphics pipeline system for Python, +#' the rasterly API has several core elements in common with that software package. #' -#' @return An environment wrapped by a list +#' A raster may be described as a matrix of cells or pixels arranged in grid-like +#' fashion, in which each pixel represents a value in the source data. +#' +#' When combined with the \link{plotly} package and Plotly.js, +#' rasterly enables analysts to generate interactive figures with +#' very large datasets which are responsive enough to embed into +#' Dash for R applications. #' #' @note Calling `rasterly()` without providing `rasterly_...()` layers has no effect. #' More info can be found in \href{https://github.com/plotly/rasterly/blob/master/README.md}{README.md} #' -#' @seealso \link{rasterize_points}, \link{rasterly_build}, \link{[.rasterly}, \link{[<-.rasterly} -#' @details -#' \itemize{ -#' \item{}{The rasterly package currently supports five aesthetics via `aes()`: "x", "y", "on", "color", and "size". -#' The "on" aesthetic specifies the variable upon which the reduction function should be applied to generate the raster data. -#' } -#' \item{}{`drop_data` can help save space, particularly when large datasets are used. However, dropping the original dataset -#' may result in errors when attempting to set or update `aes()` parameters within rasterly layers. -#' } -#' } -#' \ No newline at end of file +#' @seealso \link{rasterize_points}, \link{rasterly_build}, \link{[.rasterly}, \link{[<-.rasterly} \ No newline at end of file diff --git a/R/rasterly.R b/R/rasterly.R index fe68c94..740eef8 100644 --- a/R/rasterly.R +++ b/R/rasterly.R @@ -1,13 +1,50 @@ +#' @title rasterly +#' @description Create a rasterly object, to which aggregation layers may be added. This function is the first step in the process +#' of generating raster image data using the `rasterly` package. +#' @param data Dataset to use for generating the plot. If not provided, data must be supplied in each layer of the plot. +#' For best performance, particularly when processing large datasets, use of \link[data.table]{data.table} is recommended. +#' @param mapping Default list of aesthetic mappings to use for plot. The same with `ggplot2` \link[ggplot2]{aes}. +#' See details. +#' @param ... Other arguments which will be passed through to layers. +#' @param plot_width Integer. The width of the image to plot; must be a positive integer. A higher value indicates a higher resolution. +#' @param plot_height Integer. The height of the image to plot; must be a positive integer. A higher value indicates a higher resolution. +#' @param x_range Vector of type numeric. The range of `x`; it can be used to clip the image. For larger datasets, providing `x_range` +#' may result in improved performance. +#' @param y_range Vector of type numeric. The range of `y`; it can be used to clip the image. For larger datasets, providing `y_range` +#' may result in improved performance. +#' @param background Character. The background color of the image to plot. +#' @param color_map Vector of type character. Color(s) used to draw each pixel. The `color_map` is extended by linear interpolation +#' independently for RGB. The darkness of the mapped color depends upon the values of the aggregation matrix. +#' @param color_key Vector of type character. The `color_key` is used for categorical variables; it is passed when the `color` aesthetic +#' is provided. +#' @param show_raster Logical. Should the raster be displayed? +#' @param drop_data Logical. When working with large datasets, drops the original data once processed according to the provided +#' `aes()` parameters, using the `remove()` function. See details for additional information. +#' @param variable_check Logical. If `TRUE`, drops unused columns to save memory; may result in reduced performance. +#' +#' @return An environment wrapped by a list +#' +#' @note Calling `rasterly()` without providing `rasterly_...()` layers has no effect. +#' More info can be found in \href{https://github.com/plotly/rasterly/blob/master/README.md}{README.md} +#' +#' @seealso \link{rasterize_points}, \link{rasterly_build}, \link{[.rasterly}, \link{[<-.rasterly} +#' @details +#' \itemize{ +#' \item{}{The rasterly package currently supports five aesthetics via `aes()`: "x", "y", "on", "color", and "size". +#' The "on" aesthetic specifies the variable upon which the reduction function should be applied to generate the raster data. +#' } +#' \item{}{`drop_data` can help save space, particularly when large datasets are used. However, dropping the original dataset +#' may result in errors when attempting to set or update `aes()` parameters within rasterly layers. +#' } +#' } +#' #' @useDynLib rasterly #' @import Rcpp #' @import rlang #' @import methods #' @importFrom grDevices rgb col2rgb hcl extendrange as.raster -#' @importFrom magrittr '%>%' #' @importFrom stats ecdf approx setNames na.omit -#' @importFrom ggplot2 aes #' @importFrom data.table data.table -#' @importFrom compiler cmpfun #' @export rasterly <- function(data = NULL, mapping = aes(), diff --git a/R/reexports.R b/R/reexports.R index 9e387ec..97abc81 100644 --- a/R/reexports.R +++ b/R/reexports.R @@ -1,5 +1,7 @@ +#' @importFrom magrittr '%>%' #' @export magrittr::'%>%' +#' @importFrom ggplot2 aes #' @export ggplot2::aes diff --git a/README.md b/README.md index 3be26bb..009d2dc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # rasterly [![Build Status](https://travis-ci.org/z267xu/rasterly.svg?branch=master)](https://travis-ci.org/z267xu/rasterly) +[![Codecov test coverage](https://codecov.io/gh/z267xu/rasterly/branch/master/graph/badge.svg)](https://codecov.io/gh/z267xu/rasterly?branch=master) Easily and rapidly visualize very large datasets with R and the `plotly` package. @@ -82,7 +83,28 @@ Note that, "p" is a list of environments. The display info can be accessed throu r <- rasterly_build(p) str(r) ``` +<<<<<<< HEAD +"r" contains image raster and other useful info (like numeric aggregation matrices) to produce image but it does **not** provide any graphs. + +#### Static graph + +* `grid` +``` +# same with plot(p) +p +``` + +#### Interactive graph + +* `plotly` +``` +plot_ly(ridesDf, x = ~Lat, y = ~Lon) %>% + add_rasterly_heatmap() +``` +![](man/figures/add_rasterizer.gif) +======= "r" contains image raster and other useful info (like numeric aggregation matrices) required to produce the image but it does **not** provide any graphs. +>>>>>>> 6f569b246c3e8c0547174853d5778250bf20d2aa ## Example use in an interactive web application diff --git a/_pkgdown.yml b/_pkgdown.yml index 9445a30..d88a288 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -15,7 +15,8 @@ reference: - title: Functions desc: Functions for changing ggplot structures into loon contents: - - add_rasterly + - add_rasterly_heatmap - rasterly - rasterly_build - - rasterize_points \ No newline at end of file + - rasterize_points + - is.rasterly \ No newline at end of file diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..8f36b6c --- /dev/null +++ b/codecov.yml @@ -0,0 +1,12 @@ +comment: false + +coverage: + status: + project: + default: + target: auto + threshold: 1% + patch: + default: + target: auto + threshold: 1% diff --git a/man/add_rasterly.Rd b/man/add_rasterly.Rd deleted file mode 100644 index 140de80..0000000 --- a/man/add_rasterly.Rd +++ /dev/null @@ -1,78 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/add_rasterly.R -\name{add_rasterly} -\alias{add_rasterly} -\title{Add "rasterly" trace to a Plotly visualization} -\usage{ -add_rasterly(p, x = NULL, y = NULL, z = NULL, ..., data = NULL, - inherit = TRUE, on = NULL, size = NULL, scaling = NULL) -} -\arguments{ -\item{p}{A \code{plotly} object} - -\item{x}{Numeric vector or expression. The x variable, to be passed on to `aes()`.} - -\item{y}{Numeric or expression. The y variable, to be passed on to `aes()`.} - -\item{z}{Numeric. A numeric matrix (optional), to be processed with `add_heatmap`.} - -\item{...}{Arguments (i.e., attributes) passed along to the trace type or `rasterly`.} - -\item{data}{A data.frame or \link[crosstalk]{SharedData} object (optional).} - -\item{inherit}{Logical. Inherit attributes from \link[plotly]{plotly}?} - -\item{on}{Numeric vector or expression. Provides the data on which to reduce, to be passed on to `aes()`.} - -\item{size}{Numeric vector or expression. Pixel size for each observation, to be passed on to `aes()`.} - -\item{scaling}{Character string or function. The scaling method to be used for the trace.} -} -\description{ -Add trace to a Plotly visualization. -} -\examples{ -\dontrun{ - library(rasterly) - if(requireNamespace("plotly") && requireNamespace("data.table")) { - # Load data - ridesRaw_1 <- "https://raw.githubusercontent.com/plotly/datasets/ - master/uber-rides-data1.csv" \%>\% - data.table::fread(stringsAsFactors = FALSE) - ridesRaw_2 <- "https://raw.githubusercontent.com/plotly/datasets/ - master/uber-rides-data2.csv" \%>\% - data.table::fread(stringsAsFactors = FALSE) - ridesRaw_3 <- "https://raw.githubusercontent.com/plotly/datasets/ - master/uber-rides-data3.csv" \%>\% - data.table::fread(stringsAsFactors = FALSE) - ridesDf <- list(ridesRaw_1, ridesRaw_2, ridesRaw_3) \%>\% - data.table::rbindlist() - - #### quick start - p <- plot_ly(data = ridesDf) \%>\% - add_rasterly(x = ~Lat, y = ~Lon) - p - #### set artificial scaling function - zeroOneTransform <- function(z) { - minz <- min(z) - maxz <- max(z) - M <- matrix((z - minz)/(maxz - minz), nrow = dim(z)[1]) - return(M) - } - plot_ly(data = ridesDf) \%>\% - add_rasterly(x = ~Lat, - y = ~Lon, - on = ~-Lat, - reduction_func = "max", - scaling = zeroOneTransform) \%>\% - plotly::layout( - xaxis = list( - title = "x" - ), - yaxis = list( - title = "y" - ) - ) - } -} -} diff --git a/man/add_rasterly_heatmap.Rd b/man/add_rasterly_heatmap.Rd new file mode 100644 index 0000000..598e469 --- /dev/null +++ b/man/add_rasterly_heatmap.Rd @@ -0,0 +1,80 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/add_rasterly_heatmap.R +\name{add_rasterly_heatmap} +\alias{add_rasterly_heatmap} +\title{Add "rasterly" trace to a Plotly visualization} +\usage{ +add_rasterly_heatmap(p, x = NULL, y = NULL, z = NULL, ..., + data = NULL, inherit = TRUE, on = NULL, size = NULL, + scaling = NULL) +} +\arguments{ +\item{p}{A \code{plotly} object} + +\item{x}{Numeric vector or expression. The x variable, to be passed on to `aes()`.} + +\item{y}{Numeric or expression. The y variable, to be passed on to `aes()`.} + +\item{z}{Numeric. A numeric matrix (optional), to be processed with `add_heatmap`.} + +\item{...}{Arguments (i.e., attributes) passed along to the trace type or `rasterly`.} + +\item{data}{A data.frame or \link[crosstalk]{SharedData} object (optional).} + +\item{inherit}{Logical. Inherit attributes from \link[plotly]{plotly}?} + +\item{on}{Numeric vector or expression. Provides the data on which to reduce, to be passed on to `aes()`.} + +\item{size}{Numeric vector or expression. Pixel size for each observation, to be passed on to `aes()`.} + +\item{scaling}{Character string or function. The scaling method to be used for the trace.} +} +\description{ +Add trace to a Plotly visualization. +} +\examples{ +\dontrun{ +library(rasterly) +if(requireNamespace("plotly") && requireNamespace("data.table")) { + # Load data + url1 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data1.csv" + ridesRaw_1 <- url1 \%>\% + data.table::fread(stringsAsFactors = FALSE) + url2 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data2.csv" + ridesRaw_2 <- url2 \%>\% + data.table::fread(stringsAsFactors = FALSE) + url3 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data3.csv" + ridesRaw_3 <- url3 \%>\% + data.table::fread(stringsAsFactors = FALSE) + + ridesDf <- list(ridesRaw_1, ridesRaw_2, ridesRaw_3) \%>\% + data.table::rbindlist() + + #### quick start + p <- plot_ly(data = ridesDf) \%>\% + add_rasterly_heatmap(x = ~Lat, y = ~Lon) + p + #### set artificial scaling function + zeroOneTransform <- function(z) { + minz <- min(z) + maxz <- max(z) + M <- matrix((z - minz)/(maxz - minz), nrow = dim(z)[1]) + return(M) + } + plot_ly(data = ridesDf) \%>\% + add_rasterly_heatmap(x = ~Lat, + y = ~Lon, + on = ~-Lat, + reduction_func = "max", + scaling = zeroOneTransform) \%>\% + plotly::layout( + xaxis = list( + title = "x" + ), + yaxis = list( + title = "y" + ) + ) + } +} +} diff --git a/man/figures/logo.png b/man/figures/logo.png index 6a16d16..3761ed5 100644 Binary files a/man/figures/logo.png and b/man/figures/logo.png differ diff --git a/man/plotly.rasterly.Rd b/man/plotly.rasterly.Rd index 411ddc9..98ee91c 100644 --- a/man/plotly.rasterly.Rd +++ b/man/plotly.rasterly.Rd @@ -10,7 +10,7 @@ plotly.rasterly(rastObj, as_heatmap = FALSE, scaling = NULL, \arguments{ \item{rastObj}{A rasterly object} -\item{as_heatmap}{Draw `plotly` by adding heatmap layer. See \code{add_rasterly}} +\item{as_heatmap}{Draw `plotly` by adding heatmap layer. See \code{add_rasterly_heatmap}} \item{scaling}{It could be an artificial function or a scaling way ("log", "origin")} diff --git a/man/rasterly-package.Rd b/man/rasterly-package.Rd index 6ca0f37..b737c91 100644 --- a/man/rasterly-package.Rd +++ b/man/rasterly-package.Rd @@ -1,6 +1,5 @@ \docType{package} \name{rasterly-package} -\alias{rasterly} \alias{rasterly-package} \title{Easily and rapidly generate raster image data for large datasets using Plotly.js} \description{ @@ -12,86 +11,12 @@ A raster may be described as a matrix of cells or pixels arranged in grid-like f When combined with the \link{plotly} package and Plotly.js, rasterly enables analysts to generate interactive figures with very large datasets which are responsive enough to embed into Dash for R applications. } -\usage{ -rasterly(data = NULL, mapping = aes(), ..., plot_width = 600, - plot_height = 600, x_range = NULL, y_range = NULL, - background = "white", color_map = c("lightblue", "darkblue"), - color_key = NULL, show_raster = TRUE, drop_data = FALSE, - variable_check = FALSE) -} -\arguments{ -\item{data}{Dataset to use for generating the plot. If not provided, data must be supplied in each layer of the plot. -For best performance, particularly when processing large datasets, use of \link[data.table]{data.table} is recommended.} - -\item{mapping}{Default list of aesthetic mappings to use for plot. The same with `ggplot2` \link[ggplot2]{aes}. -See details.} - -\item{...}{Other arguments which will be passed through to layers.} - -\item{plot_width}{Integer. The width of the image to plot; must be a positive integer. A higher value indicates a higher resolution.} - -\item{plot_height}{Integer. The height of the image to plot; must be a positive integer. A higher value indicates a higher resolution.} - -\item{x_range}{Vector of type numeric. The range of `x`; it can be used to clip the image. For larger datasets, providing `x_range` -may result in improved performance.} - -\item{y_range}{Vector of type numeric. The range of `y`; it can be used to clip the image. For larger datasets, providing `y_range` -may result in improved performance.} - -\item{background}{Character. The background color of the image to plot.} -\item{color_map}{Vector of type character. Color(s) used to draw each pixel. The `color_map` is extended by linear interpolation -independently for RGB. The darkness of the mapped color depends upon the values of the aggregation matrix.} - -\item{color_key}{Vector of type character. The `color_key` is used for categorical variables; it is passed when the `color` aesthetic -is provided.} - -\item{show_raster}{Logical. Should the raster be displayed?} - -\item{drop_data}{Logical. When working with large datasets, drops the original data once processed according to the provided -`aes()` parameters, using the `remove()` function. See details for additional information.} - -\item{variable_check}{Logical. If `TRUE`, drops unused columns to save memory. Use of this option may result in reduced performance.} -} -\value{ -An environment wrapped by a list which defines the properties of the raster data to be generated. -} -\description{ -Create a rasterly object, to which aggregation layers may be added. This function is the first step in the process -of generating raster image data using the package. The `rasterly` function is not intended to be used in isolation, since aggregation layers are required for full functionality. -} -\details{ -\itemize{ - \item{}{The rasterly package currently supports five aesthetics via `aes()`: "x", "y", "on", "color", and "size". - The "on" aesthetic specifies the variable upon which the reduction function should be applied to generate the raster data. - } - \item{}{`drop_data` can help save space, particularly when large datasets are used. However, dropping the original dataset - may result in errors when attempting to set or update `aes()` parameters within rasterly layers. -} -} -} \note{ Calling `rasterly()` without providing `rasterly_...()` layers has no effect. -More info can be found in \href{https://github.com/plotly/rasterly/blob/master/README.md}{README.md}. -} -\examples{ -\dontrun{ -# Load data -ridesRaw_1 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data1.csv" %>% - data.table::fread(stringsAsFactors = FALSE) -ridesRaw_2 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data2.csv" %>% - data.table::fread(stringsAsFactors = FALSE) -ridesRaw_3 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data3.csv" %>% - data.table::fread(stringsAsFactors = FALSE) -ridesDf <- list(ridesRaw_1, ridesRaw_2, ridesRaw_3) %>% - data.table::rbindlist() - -ridesDf %>% - rasterly(mapping = aes(x = Lat, y = Lon)) %>% - rasterize_points() -> p -p -} +More info can be found in \href{https://github.com/plotly/rasterly/blob/master/README.md}{README.md} } + \seealso{ \itemize{ \link{rasterize_points}, \link{rasterly_build}, \link{[.rasterly}, \link{[<-.rasterly} @@ -100,3 +25,18 @@ p \item Please report bugs at \url{https://github.com/plotly/rasterly/issues} } } + +\author{ +\strong{Maintainer}: Zehao Xu \email{z267xu@uwaterloo.ca} + +Authors: +\itemize{ + \item Zehao Xu \email{z267xu@uwaterloo.ca} + \item Ryan Patrick Kyle \email{ryan@plot.ly} +} + +Other contributors: +\itemize{ + \item Plotly Technologies [copyright holder] +} +} diff --git a/src/RcppExports.o b/src/RcppExports.o deleted file mode 100644 index d1020bd..0000000 Binary files a/src/RcppExports.o and /dev/null differ diff --git a/tests/testthat.R b/tests/testthat.R index 7089aff..5c3ee05 100644 --- a/tests/testthat.R +++ b/tests/testthat.R @@ -1,4 +1,4 @@ - library(testthat) library(rasterly) +test_check("rasterly") \ No newline at end of file diff --git a/tests/testthat/test_rasterizer.R b/tests/testthat/test_rasterizer.R index d1d3c43..8fb10b5 100644 --- a/tests/testthat/test_rasterizer.R +++ b/tests/testthat/test_rasterizer.R @@ -2,6 +2,7 @@ context("test examples") library(data.table) library(magrittr) library(grid) +library(plotly) library(rasterly) data <- data.table::data.table(x = rnorm(1e5), y = rnorm(1e5), z = sample(1:5, 1e5, replace = TRUE)) @@ -183,4 +184,10 @@ test_that("example works", { rasterize_points(color_map = fire, group_by_data_table = FALSE) %>% rasterly_build() -> ds expect_equal(is.rasterly(ds), TRUE) + + # add_rasterly_heatmap + p <- plot_ly(data = data) %>% + add_rasterly_heatmap(x = ~x, y = ~y) + p + expect_equal(inherits(p, "plotly"), TRUE) }) diff --git a/vignettes/introduction.Rmd b/vignettes/introduction.Rmd index 66c247e..c5cfd7f 100644 --- a/vignettes/introduction.Rmd +++ b/vignettes/introduction.Rmd @@ -123,17 +123,17 @@ It contains: #### `plotly` graphics - + `add_rasterly()`: Layers are added to Plotly objects via `add_trace(...)`; `rasterly` provides the `add_rasterly()` function which also leverages `add_heatmap()` to generate single channel heatmap overlays for Plotly figures. Multi-channel heatmaps are not currently supported; this feature will be available in an upcoming release. + + `add_rasterly_heatmap()`: Layers are added to Plotly objects via `add_trace(...)`; `rasterly` provides the `add_rasterly_heatmap()` function which also leverages `add_heatmap()` to generate single channel heatmap overlays for Plotly figures. Multi-channel heatmaps are not currently supported; this feature will be available in an upcoming release. - ```{r add_rasterly, fig.width = 4, fig.height = 3} + ```{r add_rasterly_heatmap, fig.width = 4, fig.height = 3} plotly::plot_ly(ridesDf, x = ~Lat, y = ~Lon) %>% - add_rasterly() %>% + add_rasterly_heatmap() %>% layout( title = "Uber drives", - x <- list( + x = list( title = "Lat" ), - y <- list( + y = list( title = "Lon" ) )