├── _pkgdown.yml ├── .gitattributes ├── .Rproj.user ├── shared │ └── notebooks │ │ └── patch-chunk-names └── 84277BCC │ └── cpp-complilation-config ├── docs ├── _config.yml ├── logo.png ├── reference │ ├── rplot-1.png │ ├── rplot-2.png │ ├── rplot-3.png │ ├── static-1.png │ ├── static-2.png │ ├── static-3.png │ ├── static-4.png │ ├── figures │ │ ├── logo.png │ │ ├── add_rasterizer.gif │ │ ├── grid_rasterizer.png │ │ └── plotly_rasterizer.gif │ ├── image2data-1.png │ ├── reexports.html │ ├── is.rasterly.html │ ├── color_map.html │ └── is.rasterlyBuild.html ├── pkgdown.yml ├── articles │ ├── images │ │ └── introduction │ │ │ ├── anyAgg.png │ │ │ ├── darkBg.png │ │ │ ├── ggUber.png │ │ │ ├── meanAgg.png │ │ │ ├── image2data.png │ │ │ ├── uberBasic.png │ │ │ ├── uberColor.png │ │ │ ├── add_rasterizer.gif │ │ │ └── uberColorCover.png │ └── index.html ├── link.svg ├── docsearch.js ├── pkgdown.js ├── pkgdown.css ├── LICENSE-text.html ├── 404.html └── authors.html ├── LICENSE ├── src-x64 ├── aggCpp.o ├── RcppExports.o ├── rasterly.dll └── aggregationCpp.o ├── src-i386 ├── aggCpp.o ├── rasterly.dll ├── RcppExports.o └── aggregationCpp.o ├── man ├── figures │ ├── logo.png │ ├── add_rasterizer.gif │ ├── grid_rasterizer.png │ └── plotly_rasterizer.gif ├── is.rasterly.Rd ├── is.rasterlyBuild.Rd ├── reexports.Rd ├── color_map.Rd ├── rasterly_build.Rd ├── grapes-set-grapes.Rd ├── rasterly_guides.Rd ├── image2data.Rd ├── rasterly-package.Rd ├── extract.Rd ├── rasterize_points.Rd ├── rplot.Rd ├── add_rasterly.Rd ├── rasterly.Rd ├── ggRasterly.Rd ├── plotRasterly.Rd ├── rasterly_points.Rd └── static.Rd ├── tests ├── testthat.R └── testthat │ └── Rplots.pdf ├── pkgdown └── favicon │ ├── favicon.ico │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── apple-touch-icon.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ └── apple-touch-icon-180x180.png ├── R ├── rasterly-package.R ├── reexports.R ├── color_setting.R ├── is_rasterly.R ├── unreported_functions.R ├── get_aggregation_sd.R ├── get_aggregation_var.R ├── get_aggregation_m2.R ├── rasterize_points.R ├── merge_operator.R ├── rasterly_guides.R ├── get_aggregation_any.R ├── get_aggregation_max.R ├── get_aggregation_min.R ├── extract.R ├── get_aggregation_last.R ├── get_aggregation_first.R ├── get_aggregation_sum.R ├── image2data.R ├── add_rasterly_image.R ├── utils.R ├── RcppExports.R ├── get_aesthetics.R ├── rplot.R ├── get_arguments.R ├── as_raster.R ├── plotRasterly.R ├── rasterly.R └── add_rasterly_heatmap.R ├── .gitignore ├── vignettes ├── images │ └── introduction │ │ ├── anyAgg.png │ │ ├── darkBg.png │ │ ├── ggUber.png │ │ ├── meanAgg.png │ │ ├── uberBasic.png │ │ ├── uberColor.png │ │ ├── image2data.png │ │ ├── add_rasterizer.gif │ │ └── uberColorCover.png └── introduction.html.asis ├── .Rbuildignore ├── codecov.yml ├── rasterly.Rproj ├── .travis.yml ├── DESCRIPTION ├── NAMESPACE └── README.md /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | destination: docs 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | src/* linguist-vendored 2 | -------------------------------------------------------------------------------- /.Rproj.user/shared/notebooks/patch-chunk-names: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-architect -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2019 2 | COPYRIGHT HOLDER: Plotly, Inc. 3 | -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/logo.png -------------------------------------------------------------------------------- /src-x64/aggCpp.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/src-x64/aggCpp.o -------------------------------------------------------------------------------- /src-i386/aggCpp.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/src-i386/aggCpp.o -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/man/figures/logo.png -------------------------------------------------------------------------------- /src-i386/rasterly.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/src-i386/rasterly.dll -------------------------------------------------------------------------------- /src-x64/RcppExports.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/src-x64/RcppExports.o -------------------------------------------------------------------------------- /src-x64/rasterly.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/src-x64/rasterly.dll -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(rasterly) 3 | 4 | test_check("rasterly") 5 | -------------------------------------------------------------------------------- /src-i386/RcppExports.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/src-i386/RcppExports.o -------------------------------------------------------------------------------- /docs/reference/rplot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/reference/rplot-1.png -------------------------------------------------------------------------------- /docs/reference/rplot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/reference/rplot-2.png -------------------------------------------------------------------------------- /docs/reference/rplot-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/reference/rplot-3.png -------------------------------------------------------------------------------- /src-i386/aggregationCpp.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/src-i386/aggregationCpp.o -------------------------------------------------------------------------------- /src-x64/aggregationCpp.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/src-x64/aggregationCpp.o -------------------------------------------------------------------------------- /tests/testthat/Rplots.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/tests/testthat/Rplots.pdf -------------------------------------------------------------------------------- /docs/reference/static-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/reference/static-1.png -------------------------------------------------------------------------------- /docs/reference/static-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/reference/static-2.png -------------------------------------------------------------------------------- /docs/reference/static-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/reference/static-3.png -------------------------------------------------------------------------------- /docs/reference/static-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/reference/static-4.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/pkgdown/favicon/favicon.ico -------------------------------------------------------------------------------- /R/rasterly-package.R: -------------------------------------------------------------------------------- 1 | #' @keywords internal 2 | #' @aliases rasterly-package 3 | "_PACKAGE" 4 | 5 | NULL 6 | 7 | -------------------------------------------------------------------------------- /docs/reference/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/reference/figures/logo.png -------------------------------------------------------------------------------- /docs/reference/image2data-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/reference/image2data-1.png -------------------------------------------------------------------------------- /man/figures/add_rasterizer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/man/figures/add_rasterizer.gif -------------------------------------------------------------------------------- /man/figures/grid_rasterizer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/man/figures/grid_rasterizer.png -------------------------------------------------------------------------------- /man/figures/plotly_rasterizer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/man/figures/plotly_rasterizer.gif -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/pkgdown/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/pkgdown/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/pkgdown/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | src/*.o 6 | src/*.so 7 | src/*.dll 8 | doc 9 | Meta 10 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: '2.6' 2 | pkgdown: 1.4.1 3 | pkgdown_sha: ~ 4 | articles: 5 | introduction: introduction.html 6 | 7 | -------------------------------------------------------------------------------- /docs/reference/figures/add_rasterizer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/reference/figures/add_rasterizer.gif -------------------------------------------------------------------------------- /vignettes/images/introduction/anyAgg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/vignettes/images/introduction/anyAgg.png -------------------------------------------------------------------------------- /vignettes/images/introduction/darkBg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/vignettes/images/introduction/darkBg.png -------------------------------------------------------------------------------- /vignettes/images/introduction/ggUber.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/vignettes/images/introduction/ggUber.png -------------------------------------------------------------------------------- /vignettes/images/introduction/meanAgg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/vignettes/images/introduction/meanAgg.png -------------------------------------------------------------------------------- /docs/reference/figures/grid_rasterizer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/reference/figures/grid_rasterizer.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/pkgdown/favicon/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/pkgdown/favicon/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /vignettes/images/introduction/uberBasic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/vignettes/images/introduction/uberBasic.png -------------------------------------------------------------------------------- /vignettes/images/introduction/uberColor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/vignettes/images/introduction/uberColor.png -------------------------------------------------------------------------------- /docs/articles/images/introduction/anyAgg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/articles/images/introduction/anyAgg.png -------------------------------------------------------------------------------- /docs/articles/images/introduction/darkBg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/articles/images/introduction/darkBg.png -------------------------------------------------------------------------------- /docs/articles/images/introduction/ggUber.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/articles/images/introduction/ggUber.png -------------------------------------------------------------------------------- /docs/articles/images/introduction/meanAgg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/articles/images/introduction/meanAgg.png -------------------------------------------------------------------------------- /docs/reference/figures/plotly_rasterizer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/reference/figures/plotly_rasterizer.gif -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/pkgdown/favicon/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/pkgdown/favicon/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/pkgdown/favicon/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /vignettes/images/introduction/image2data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/vignettes/images/introduction/image2data.png -------------------------------------------------------------------------------- /vignettes/introduction.html.asis: -------------------------------------------------------------------------------- 1 | %\VignetteEngine{knitr::knitr} 2 | %\VignetteIndexEntry{Introduction} 3 | %\usepackage[utf8]{inputenc} 4 | -------------------------------------------------------------------------------- /docs/articles/images/introduction/image2data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/articles/images/introduction/image2data.png -------------------------------------------------------------------------------- /docs/articles/images/introduction/uberBasic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/articles/images/introduction/uberBasic.png -------------------------------------------------------------------------------- /docs/articles/images/introduction/uberColor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/articles/images/introduction/uberColor.png -------------------------------------------------------------------------------- /vignettes/images/introduction/add_rasterizer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/vignettes/images/introduction/add_rasterizer.gif -------------------------------------------------------------------------------- /vignettes/images/introduction/uberColorCover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/vignettes/images/introduction/uberColorCover.png -------------------------------------------------------------------------------- /R/reexports.R: -------------------------------------------------------------------------------- 1 | #' @importFrom magrittr '%>%' 2 | #' @export 3 | magrittr::'%>%' 4 | 5 | #' @importFrom ggplot2 aes 6 | #' @export 7 | ggplot2::aes 8 | -------------------------------------------------------------------------------- /docs/articles/images/introduction/add_rasterizer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/articles/images/introduction/add_rasterizer.gif -------------------------------------------------------------------------------- /docs/articles/images/introduction/uberColorCover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plotly/rasterly/HEAD/docs/articles/images/introduction/uberColorCover.png -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^doc$ 4 | ^Meta$ 5 | .gitignore 6 | .travis.yml 7 | _pkgdown.yml 8 | README.md 9 | NEWS.md 10 | codecov.yml 11 | ^_pkgdown\.yml$ 12 | ^docs$ 13 | ^pkgdown$ 14 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | status: 5 | project: 6 | default: 7 | target: auto 8 | threshold: 1% 9 | patch: 10 | default: 11 | target: auto 12 | threshold: 1% 13 | -------------------------------------------------------------------------------- /man/is.rasterly.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/is_rasterly.R 3 | \name{is.rasterly} 4 | \alias{is.rasterly} 5 | \title{Is \code{rasterly}} 6 | \usage{ 7 | is.rasterly(x) 8 | } 9 | \arguments{ 10 | \item{x}{a \code{rasterly} object} 11 | } 12 | \description{ 13 | Reports whether x is a \code{rasterly} object. 14 | } 15 | -------------------------------------------------------------------------------- /.Rproj.user/84277BCC/cpp-complilation-config: -------------------------------------------------------------------------------- 1 | { 2 | "args" : [ 3 | "-IE:/Rstudio/resources/libclang/builtin-headers/5.0.2", 4 | "-IE:/Rstudio/resources/libclang/builtin-headers/libc++/5.0.2", 5 | "-IE:/R-3.6.3/library/Rcpp/include", 6 | "-std=gnu++11", 7 | "-IE:/R-3.6.3/include", 8 | "-DNDEBUG" 9 | ], 10 | "hash" : "1587558325", 11 | "is_cpp" : true, 12 | "pch" : "Rcpp" 13 | } -------------------------------------------------------------------------------- /rasterly.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: ISO8859-1 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | BuildType: Package 16 | PackageUseDevtools: Yes 17 | PackageInstallArgs: --no-multiarch --with-keep.source 18 | PackageRoxygenize: rd,collate,namespace,vignette 19 | -------------------------------------------------------------------------------- /man/is.rasterlyBuild.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/is_rasterly.R 3 | \name{is.rasterlyBuild} 4 | \alias{is.rasterlyBuild} 5 | \title{Is \code{rasterlyBuild}} 6 | \usage{ 7 | is.rasterlyBuild(x) 8 | } 9 | \arguments{ 10 | \item{x}{a \code{rasterly} object} 11 | } 12 | \description{ 13 | Reports whether x is a \code{rasterlyBuild} object. In other word, it helps to define 14 | whether this object has been passed through `rasterly_build` 15 | } 16 | -------------------------------------------------------------------------------- /man/reexports.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/reexports.R 3 | \docType{import} 4 | \name{reexports} 5 | \alias{reexports} 6 | \alias{\%>\%} 7 | \alias{aes} 8 | \title{Objects exported from other packages} 9 | \keyword{internal} 10 | \description{ 11 | These objects are imported from other packages. Follow the links 12 | below to see their documentation. 13 | 14 | \describe{ 15 | \item{ggplot2}{\code{\link[ggplot2]{aes}}} 16 | 17 | \item{magrittr}{\code{\link[magrittr]{\%>\%}}} 18 | }} 19 | 20 | -------------------------------------------------------------------------------- /R/color_setting.R: -------------------------------------------------------------------------------- 1 | get_rgb_num <- function(color) { 2 | rgb_num <- grDevices::col2rgb(color) 3 | list( 4 | red = rgb_num['red', ], 5 | green = rgb_num['green', ], 6 | blue = rgb_num['blue', ] 7 | ) 8 | } 9 | 10 | interpolation <- function(..., span = NULL) { 11 | 12 | if(is.null(span)) span <- 50 # default setting in approx 13 | args <- list(...) 14 | lapply(args, 15 | function(arg){ 16 | stats::approx(x = arg, n = span)[['y']] 17 | }) 18 | 19 | } 20 | 21 | gg_color_hue <- function(n) { 22 | hues <- seq(15, 375, length = n + 1) 23 | grDevices::hcl(h = hues, l = 65, c = 100)[1:n] 24 | } 25 | -------------------------------------------------------------------------------- /R/is_rasterly.R: -------------------------------------------------------------------------------- 1 | #' @title Is \code{rasterly} 2 | #' @description Reports whether x is a \code{rasterly} object. 3 | #' @param x a \code{rasterly} object 4 | #' @export 5 | is.rasterly <- function(x) { 6 | inherits(x, "rasterly") 7 | } 8 | 9 | #' @title Is \code{rasterlyBuild} 10 | #' @description Reports whether x is a \code{rasterlyBuild} object. In other word, it helps to define 11 | #' whether this object has been passed through `rasterly_build` 12 | #' @param x a \code{rasterly} object 13 | #' @export 14 | is.rasterlyBuild <- function(x) { 15 | inherits(x, "rasterlyBuild") 16 | } 17 | 18 | is.rasterlyLayer <- function(x) { 19 | inherits(x, "rasterlyLayer") 20 | } 21 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | addons: 2 | apt: 3 | packages: 4 | - libtk-img 5 | - mesa-common-dev 6 | - libglu1-mesa-dev 7 | - freeglut3-dev 8 | - libssl-dev 9 | - libcurl4-gnutls-dev 10 | - libxml2-dev 11 | - xvfb 12 | 13 | sudo: false 14 | 15 | language: r 16 | r_github_packages: 17 | - r-lib/covr 18 | 19 | before_install: 20 | - export DISPLAY=':99.0' 21 | - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & 22 | - R -q -e 'install.packages(c("Rcpp", "ggplot2", "data.table", "plotly", "magrittr","rlang","testthat","knitr","rmarkdown", "png"))' 23 | 24 | cache: packages 25 | 26 | r: 27 | - release 28 | - devel 29 | 30 | after_success: 31 | - Rscript -e 'covr::codecov()' -------------------------------------------------------------------------------- /R/unreported_functions.R: -------------------------------------------------------------------------------- 1 | ################################ Unreported functions in `ggplot2` and `plotly` 2 | # Reason: Avoid `:::` to pass R CMD check 3 | 4 | ## Unexported functions in ggplot2 5 | new_aes <- getFromNamespace("new_aes", "ggplot2") 6 | 7 | new_aesthetic <- getFromNamespace("new_aesthetic", "ggplot2") 8 | 9 | ## Unexported functions in plotly 10 | add_trace_classed <- function(p, class = "plotly_polygon", ...) { 11 | p <- plotly::add_trace(p, ...) 12 | nAttrs <- length(p$x$attrs) 13 | p$x$attrs[[nAttrs]] <- prefix_class(p$x$attrs[[nAttrs]], class) 14 | p 15 | } 16 | 17 | prefix_class <- function(x, y) { 18 | structure(x, class = unique(c(y, class(x)))) 19 | } 20 | -------------------------------------------------------------------------------- /man/color_map.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/colorMaps.R 3 | \docType{data} 4 | \name{color_map} 5 | \alias{color_map} 6 | \alias{fire_map} 7 | \alias{viridis_map} 8 | \alias{hourColors_map} 9 | \title{Supplemental color maps for rasterly} 10 | \format{ 11 | An object of class \code{character} of length 256. 12 | 13 | An object of class \code{character} of length 256. 14 | 15 | An object of class \code{character} of length 24. 16 | } 17 | \usage{ 18 | fire_map 19 | 20 | viridis_map 21 | 22 | hourColors_map 23 | } 24 | \description{ 25 | Hex codes for the color map. 26 | Used in setting argument \code{color} in \code{rasterly} or \code{rasterly} layers. 27 | } 28 | \keyword{datasets} 29 | -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /man/rasterly_build.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rasterly_build.R 3 | \name{rasterly_build} 4 | \alias{rasterly_build} 5 | \title{rasterly_build} 6 | \usage{ 7 | rasterly_build(rastObj) 8 | } 9 | \arguments{ 10 | \item{rastObj}{A rasterly object. It should be a list of environments composed of a \code{rasterly()} and 11 | several \code{rasterly_...} layers.} 12 | } 13 | \description{ 14 | Produce a rasterly object and return the raster information required to produce an image 15 | } 16 | \note{ 17 | A rasterly object will never be produced until \code{rasterly_build()} is called. 18 | } 19 | \examples{ 20 | r <- data.frame(x = rnorm(1e5), y = rnorm(1e5)) \%>\% 21 | rasterly(mapping = aes(x = x, y = y)) \%>\% 22 | rasterly_points(color = fire_map) 23 | str(r) 24 | p <- rasterly_build(r) 25 | str(p) 26 | } 27 | \seealso{ 28 | \link{rasterly}, \link{rasterly_points}, \link{[.rasterly}, \link{[<-.rasterly} 29 | } 30 | -------------------------------------------------------------------------------- /R/get_aggregation_sd.R: -------------------------------------------------------------------------------- 1 | get_aggregation.var <- function(plot_width, plot_height, aesthetics, 2 | x_range, y_range, xlim, ylim, 3 | func, glyph, group_by_data_table, ...) { 4 | 5 | if(is.null(aesthetics$on)) stop("No `on` argument was provided. Which variable should be used for sum of square differences from the mean?") 6 | is_size <- !is.null(aesthetics$size) 7 | is_color <- !is.null(aesthetics$color) 8 | 9 | aesthetics$on <- stats::sd(aesthetics$on) 10 | get_aggregation.sum(plot_width = plot_width, 11 | plot_height = plot_height, 12 | aesthetics = aesthetics, 13 | x_range = x_range, 14 | y_range = y_range, 15 | xlim = xlim, 16 | ylim = ylim, 17 | func = NULL, 18 | glyph = glyph, 19 | group_by_data_table = group_by_data_table, ...) 20 | } 21 | -------------------------------------------------------------------------------- /R/get_aggregation_var.R: -------------------------------------------------------------------------------- 1 | get_aggregation.var <- function(plot_width, plot_height, aesthetics, 2 | x_range, y_range, xlim, ylim, 3 | func, glyph, group_by_data_table, ...) { 4 | 5 | if(is.null(aesthetics$on)) stop("No `on` argument was provided. Which variable should be used for sum of square differences from the mean?") 6 | is_size <- !is.null(aesthetics$size) 7 | is_color <- !is.null(aesthetics$color) 8 | 9 | aesthetics$on <- stats::var(aesthetics$on) 10 | get_aggregation.sum(plot_width = plot_width, 11 | plot_height = plot_height, 12 | aesthetics = aesthetics, 13 | x_range = x_range, 14 | y_range = y_range, 15 | xlim = xlim, 16 | ylim = ylim, 17 | func = NULL, 18 | glyph = glyph, 19 | group_by_data_table = group_by_data_table, ...) 20 | } 21 | -------------------------------------------------------------------------------- /R/get_aggregation_m2.R: -------------------------------------------------------------------------------- 1 | get_aggregation.m2 <- function(plot_width, plot_height, aesthetics, 2 | x_range, y_range, xlim, ylim, 3 | func, glyph, group_by_data_table, ...) { 4 | 5 | if(is.null(aesthetics$on)) stop("No `on` argument was provided. Which variable should be used for sum of square differences from the mean?") 6 | is_size <- !is.null(aesthetics$size) 7 | is_color <- !is.null(aesthetics$color) 8 | 9 | aesthetics$on <- (aesthetics$on - mean(aesthetics$on))^2 10 | get_aggregation.sum(plot_width = plot_width, 11 | plot_height = plot_height, 12 | aesthetics = aesthetics, 13 | x_range = x_range, 14 | y_range = y_range, 15 | xlim = xlim, 16 | ylim = ylim, 17 | func = NULL, 18 | glyph = glyph, 19 | group_by_data_table = group_by_data_table, ...) 20 | } 21 | -------------------------------------------------------------------------------- /man/grapes-set-grapes.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/merge_operator.R 3 | \name{\%<-\%} 4 | \alias{\%<-\%} 5 | \title{Merge operator} 6 | \usage{ 7 | x \%<-\% y 8 | } 9 | \arguments{ 10 | \item{x}{A named list or vector} 11 | 12 | \item{y}{A named list or vector. Any duplicated names are detected in x will be covered by y} 13 | } 14 | \value{ 15 | a list 16 | } 17 | \description{ 18 | Merge two objects from right to left. 19 | } 20 | \examples{ 21 | # two lists 22 | x <- list(a = 1, b = "foo", c = 3) 23 | y <- list(b = 2, d = 4) 24 | x \%<-\% y 25 | y \%<-\% x 26 | 27 | # one list and one vector 28 | x <- c(foo = 1, bar = 2) 29 | y <- list(foo = "foo") 30 | x \%<-\% y 31 | y \%<-\% x 32 | 33 | # two vectors 34 | x <- c(a = 1, b = "foo", c = 3) 35 | y <- c(b = 2, d = 4) 36 | x \%<-\% y 37 | y \%<-\% x 38 | 39 | # duplicated names in x 40 | x <- list(a = 1, b = "foo", b = 3) 41 | y <- list(b = 2, d = 4) 42 | x \%<-\% y 43 | y \%<-\% x # be careful, since "3" will cover on "foo" in x, then on "2" in y 44 | 45 | } 46 | -------------------------------------------------------------------------------- /R/rasterize_points.R: -------------------------------------------------------------------------------- 1 | #' @title rasterize_points 2 | #' @description Points layer for "rasterly". Deprecated now, please use \code{rasterly_points} instead. 3 | #' @seealso \link{rasterly_points} 4 | #' @inheritParams rasterly_points 5 | #' @export 6 | rasterize_points <- function(rastObj, 7 | data = NULL, 8 | mapping = aes(), 9 | ..., 10 | xlim = NULL, 11 | ylim = NULL, 12 | max_size = NULL, 13 | reduction_func = NULL, 14 | layout = NULL, 15 | glyph = NULL, 16 | group_by_data_table = NULL, 17 | inherit.aes = TRUE) { 18 | warning("`rasterize_points` is deprecated. Please use `rasterly_points`.") 19 | rasterly_points( 20 | rastObj, 21 | data, 22 | mapping, 23 | ..., 24 | xlim, 25 | ylim, 26 | max_size, 27 | reduction_func, 28 | layout, 29 | glyph, 30 | group_by_data_table, 31 | inherit.aes 32 | ) 33 | } -------------------------------------------------------------------------------- /man/rasterly_guides.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rasterly_guides.R 3 | \name{rasterly_guides} 4 | \alias{rasterly_guides} 5 | \title{rasterly_guides} 6 | \usage{ 7 | rasterly_guides( 8 | rastObj, 9 | x_pretty = NULL, 10 | y_pretty = NULL, 11 | panel_background = "grey92", 12 | panel_line = "white" 13 | ) 14 | } 15 | \arguments{ 16 | \item{rastObj}{A "rasterly" object.} 17 | 18 | \item{x_pretty}{The pretty on x. Compute a sequence of about n+1 equally spaced 'round' values 19 | which cover the range of the values in x. If it is not provided, \code{x_pretty} will 20 | be generated by the x range} 21 | 22 | \item{y_pretty}{The pretty on y.} 23 | 24 | \item{panel_background}{Panel background.} 25 | 26 | \item{panel_line}{Panel line color} 27 | } 28 | \description{ 29 | Guides layer for "rasterly". 30 | } 31 | \details{ 32 | When an image has a 'complicated' background, the drawing time increases significantly. 33 | So it is not recommended. A suggestion to draw grid guides is to transform image data to a data frame 34 | via \link{image2data}, then use \code{ggplot} or \code{plotly} to display. 35 | } 36 | \seealso{ 37 | \link{ggRasterly} 38 | } 39 | -------------------------------------------------------------------------------- /man/image2data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/image2data.R 3 | \name{image2data} 4 | \alias{image2data} 5 | \title{Image raster to data frame.} 6 | \usage{ 7 | image2data(x, background = "white", x_range = NULL, y_range = NULL) 8 | } 9 | \arguments{ 10 | \item{x}{It could be a rasterly object or a raster image.} 11 | 12 | \item{background}{The background of image raster.} 13 | 14 | \item{x_range}{The range represents image width.} 15 | 16 | \item{y_range}{The range represents image height.} 17 | } 18 | \value{ 19 | a \code{data.table} object 20 | } 21 | \description{ 22 | Transform a image raster to a data frame. 23 | } 24 | \examples{ 25 | x <- rnorm(1000, mean = 10) 26 | y <- rnorm(1000, mean = 20) 27 | color <- sample(1:5, 1000, replace = TRUE) 28 | rastObj <- data.frame(x = x, y = y, color = color) \%>\% 29 | rasterly(mapping = aes(x = x, y = y, color = color)) \%>\% 30 | rasterly_points() 31 | p <- rasterly_build(rastObj) 32 | dt <- image2data(p) 33 | if(requireNamespace("ggplot2")) { 34 | # Note that each point represents a single pixel in the image 35 | ggplot2::ggplot(dt, mapping = aes(x = x, y = y)) + 36 | ggplot2::geom_point(color = dt$color, size = 0.5) 37 | } 38 | } 39 | \seealso{ 40 | \link{ggRasterly} 41 | } 42 | -------------------------------------------------------------------------------- /man/rasterly-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rasterly-package.R 3 | \docType{package} 4 | \name{rasterly-package} 5 | \alias{rasterly-package} 6 | \alias{_PACKAGE} 7 | \title{rasterly: Easily and Rapidly Generate Raster Image Data with Support for 'Plotly.js'} 8 | \description{ 9 | \if{html}{\figure{logo.png}{options: align='right' alt='logo' width='120'}} 10 | 11 | It aims to easily and rapidly generate raster data in R, even for very large datasets, with an aesthetics-based mapping syntax that should be familiar to users of the \code{ggplot2} package. While \code{rasterly} does not attempt to reproduce the full functionality of the \code{Datashader} graphics pipeline system for Python, the \code{rasterly} API has several core elements in common with that software package. 12 | } 13 | \seealso{ 14 | Useful links: 15 | \itemize{ 16 | \item Report bugs at \url{https://github.com/plotly/rasterly/issues} 17 | } 18 | 19 | } 20 | \author{ 21 | \strong{Maintainer}: Zehao Xu \email{z267xu@uwaterloo.ca} 22 | 23 | Other contributors: 24 | \itemize{ 25 | \item Ryan Patrick Kyle \email{ryan@plot.ly} (\href{https://orcid.org/0000-0001-5829-9867}{ORCID}) [contributor] 26 | \item Plotly Technologies [copyright holder] 27 | } 28 | 29 | } 30 | \keyword{internal} 31 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: rasterly 2 | Title: Easily and Rapidly Generate Raster Image Data with Support for 'Plotly.js' 3 | Version: 0.2.0 4 | Authors@R: c(person("Zehao", "Xu", role = c("aut", "cre"), email = "z267xu@uwaterloo.ca"), person("Ryan Patrick", "Kyle", role = c("ctb"), comment = c(ORCID = "0000-0001-5829-9867"), email = "ryan@plot.ly"), person(family = "Plotly Technologies", role = "cph")) 5 | Description: It aims to easily and rapidly generate raster data in R, even for very large datasets, with an aesthetics-based mapping syntax that should be familiar to users of the \code{ggplot2} package. While \code{rasterly} does not attempt to reproduce the full functionality of the \code{Datashader} graphics pipeline system for Python, the \code{rasterly} API has several core elements in common with that software package. 6 | LinkingTo: Rcpp 7 | License: MIT + file LICENSE 8 | Encoding: UTF-8 9 | ByteCompile: true 10 | KeepSource: true 11 | BugReports: https://github.com/plotly/rasterly/issues 12 | Depends: 13 | R (>= 3.4.0), 14 | methods, 15 | Rcpp 16 | Imports: 17 | data.table, 18 | rlang, 19 | plotly, 20 | ggplot2, 21 | magrittr, 22 | grid, 23 | stats 24 | Suggests: 25 | covr, 26 | testthat, 27 | knitr, 28 | rmarkdown, 29 | lubridate 30 | LazyData: true 31 | RoxygenNote: 7.1.0 32 | VignetteBuilder: knitr 33 | -------------------------------------------------------------------------------- /R/merge_operator.R: -------------------------------------------------------------------------------- 1 | #' @title Merge operator 2 | #' @description Merge two objects from right to left. 3 | #' @usage x \%<-\% y 4 | #' 5 | #' @return a list 6 | #' 7 | #' @param x A named list or vector 8 | #' @param y A named list or vector. Any duplicated names are detected in x will be covered by y 9 | #' 10 | #' @examples 11 | #' # two lists 12 | #' x <- list(a = 1, b = "foo", c = 3) 13 | #' y <- list(b = 2, d = 4) 14 | #' x %<-% y 15 | #' y %<-% x 16 | #' 17 | #' # one list and one vector 18 | #' x <- c(foo = 1, bar = 2) 19 | #' y <- list(foo = "foo") 20 | #' x %<-% y 21 | #' y %<-% x 22 | #' 23 | #' # two vectors 24 | #' x <- c(a = 1, b = "foo", c = 3) 25 | #' y <- c(b = 2, d = 4) 26 | #' x %<-% y 27 | #' y %<-% x 28 | #' 29 | #' # duplicated names in x 30 | #' x <- list(a = 1, b = "foo", b = 3) 31 | #' y <- list(b = 2, d = 4) 32 | #' x %<-% y 33 | #' y %<-% x # be careful, since "3" will cover on "foo" in x, then on "2" in y 34 | #' 35 | #' @export 36 | `%<-%` <- function(x, y) { 37 | if(is.null(names(x)) || is.null(names(y))) 38 | return(c(x,y)) 39 | else { 40 | 41 | if(!is.list(x)) x <- as.list(x) 42 | if(!is.list(y)) y <- as.list(y) 43 | 44 | merged_list <- c(x, y) 45 | list_names <- names(merged_list) 46 | merged_list[duplicated(list_names, fromLast = TRUE)] <- NULL 47 | 48 | return(merged_list[unique(list_names)]) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method("[",rasterly) 4 | S3method("[<-",rasterly) 5 | S3method(image2data,matrix) 6 | S3method(image2data,raster) 7 | S3method(image2data,rasterly) 8 | S3method(plot,rasterly) 9 | S3method(print,rasterly) 10 | S3method(rasterly_build,default) 11 | S3method(rasterly_build,rasterly) 12 | S3method(rasterly_build,rasterlyBuild) 13 | S3method(rplot,default) 14 | export("%<-%") 15 | export("%>%") 16 | export(add_rasterly_heatmap) 17 | export(add_rasterly_image) 18 | export(aes) 19 | export(fire_map) 20 | export(ggRasterly) 21 | export(grid.rasterly) 22 | export(hourColors_map) 23 | export(image2data) 24 | export(is.rasterly) 25 | export(is.rasterlyBuild) 26 | export(plotRasterly) 27 | export(rasterize_points) 28 | export(rasterly) 29 | export(rasterlyGrob) 30 | export(rasterly_build) 31 | export(rasterly_guides) 32 | export(rasterly_points) 33 | export(rplot) 34 | export(viridis_map) 35 | import(Rcpp) 36 | import(grid) 37 | import(methods) 38 | import(rlang) 39 | importFrom(data.table,data.table) 40 | importFrom(ggplot2,aes) 41 | importFrom(grDevices,as.raster) 42 | importFrom(grDevices,col2rgb) 43 | importFrom(grDevices,extendrange) 44 | importFrom(grDevices,hcl) 45 | importFrom(grDevices,rgb) 46 | importFrom(magrittr,'%>%') 47 | importFrom(stats,approx) 48 | importFrom(stats,ecdf) 49 | importFrom(stats,na.omit) 50 | importFrom(stats,setNames) 51 | useDynLib(rasterly) 52 | -------------------------------------------------------------------------------- /man/extract.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/extract.R 3 | \name{extract} 4 | \alias{extract} 5 | \alias{[.rasterly} 6 | \alias{[<-.rasterly} 7 | \title{Extract or replace parts of a \code{rasterly} object} 8 | \usage{ 9 | \method{[}{rasterly}(x, name) 10 | 11 | \method{[}{rasterly}(x, name, ...) <- value 12 | } 13 | \arguments{ 14 | \item{x}{Object from which to extract element(s) or in which to replace element(s).} 15 | 16 | \item{name}{Character. A literal string to be extracted from \code{x}. See details for more information.} 17 | 18 | \item{...}{(missing) or NULL.} 19 | 20 | \item{value}{values to replace; typically an array-like R object of a similar class as x.} 21 | } 22 | \description{ 23 | The \code{extract} function provides functionality for updating existing \code{rasterly} objects. 24 | } 25 | \details{ 26 | Available names: 27 | \itemize{ 28 | \item{Aggregation: }{"data", "mapping", "plot_width", "plot_height", "range", "x_range", 29 | "y_range", "xlim", "ylim", "aesthetics", "reduction_func", "glyph", 30 | "max_size", "group_by_data_table", "drop_data", "variable_check"} 31 | \item{Display: }{"background", "color", "alpha", "span", 32 | "show_raster", "layout"} 33 | } 34 | 35 | Set \code{level} in \code{...}. \code{level} is numeric used for specifing level of `rasterly` object to modify; 36 | default is 1 for the parent layer (\code{rasterly()}). 37 | } 38 | \examples{ 39 | library(rasterly) 40 | r <- rasterly( 41 | data = data.frame(x = 1:1e4, y = runif(1e4), category = sample(1:4, 1e4, replace = TRUE)), 42 | mapping = aes(x = x, y = y) 43 | ) \%>\% 44 | rasterly_points(xlim = c(1, 5000)) \%>\% 45 | rasterly_points( 46 | mapping = aes(x = x, y = y, color = category), 47 | xlim = c(5001, 1e4) 48 | ) 49 | r["mapping"] 50 | r["xlim"] 51 | 52 | # reassign parent `rasterly()` mapping 53 | r["mapping"] <- aes(x = x, y = y, color = category) 54 | r["mapping"] 55 | 56 | # reassign all mapping systems 57 | r["mapping", level = 1:length(r)] <- aes(x = x, y = y) 58 | r["mapping"] 59 | } 60 | -------------------------------------------------------------------------------- /R/rasterly_guides.R: -------------------------------------------------------------------------------- 1 | #' @title rasterly_guides 2 | #' @description Guides layer for "rasterly". 3 | #' @param rastObj A "rasterly" object. 4 | #' @param x_pretty The pretty on x. Compute a sequence of about n+1 equally spaced 'round' values 5 | #' which cover the range of the values in x. If it is not provided, \code{x_pretty} will 6 | #' be generated by the x range 7 | #' @param y_pretty The pretty on y. 8 | #' @param panel_background Panel background. 9 | #' @param panel_line Panel line color 10 | #' @details When an image has a 'complicated' background, the drawing time increases significantly. 11 | #' So it is not recommended. A suggestion to draw grid guides is to transform image data to a data frame 12 | #' via \link{image2data}, then use \code{ggplot} or \code{plotly} to display. 13 | #' @seealso \link{ggRasterly} 14 | #' @export 15 | rasterly_guides <- function(rastObj, 16 | x_pretty = NULL, 17 | y_pretty = NULL, 18 | panel_background = "grey92", 19 | panel_line = "white") { 20 | 21 | x_pretty <- get_x_pretty(envir = rastObj$rasterly_env, x_pretty) 22 | y_pretty <- get_x_pretty(envir = rastObj$rasterly_env, y_pretty) 23 | 24 | panel_background <- get_panel_background(envir = rastObj$rasterly_env, panel_background) 25 | panel_line <- get_panel_line(envir = rastObj$rasterly_env, panel_line) 26 | 27 | p <- structure( 28 | list(rasterly_guides = environment()), 29 | class = c("rasterlyGuides") 30 | ) 31 | rastObj <- c( 32 | rastObj, 33 | p 34 | ) 35 | class(rastObj) <- c("rasterly") 36 | invisible(return(rastObj)) 37 | } 38 | 39 | 40 | get_panel_background <- function(envir, panel_background) { 41 | 42 | parent_args <- .get("args", envir = envir) 43 | panel_background <- panel_background %||% parent_args$panel_background %||% "grey92" 44 | 45 | return(panel_background) 46 | } 47 | 48 | get_panel_line <- function(envir, panel_line) { 49 | 50 | parent_args <- .get("args", envir = envir) 51 | panel_line <- panel_line %||% parent_args$panel_line %||% "white" 52 | 53 | return(panel_line) 54 | } -------------------------------------------------------------------------------- /docs/docsearch.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | // register a handler to move the focus to the search bar 4 | // upon pressing shift + "/" (i.e. "?") 5 | $(document).on('keydown', function(e) { 6 | if (e.shiftKey && e.keyCode == 191) { 7 | e.preventDefault(); 8 | $("#search-input").focus(); 9 | } 10 | }); 11 | 12 | $(document).ready(function() { 13 | // do keyword highlighting 14 | /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ 15 | var mark = function() { 16 | 17 | var referrer = document.URL ; 18 | var paramKey = "q" ; 19 | 20 | if (referrer.indexOf("?") !== -1) { 21 | var qs = referrer.substr(referrer.indexOf('?') + 1); 22 | var qs_noanchor = qs.split('#')[0]; 23 | var qsa = qs_noanchor.split('&'); 24 | var keyword = ""; 25 | 26 | for (var i = 0; i < qsa.length; i++) { 27 | var currentParam = qsa[i].split('='); 28 | 29 | if (currentParam.length !== 2) { 30 | continue; 31 | } 32 | 33 | if (currentParam[0] == paramKey) { 34 | keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); 35 | } 36 | } 37 | 38 | if (keyword !== "") { 39 | $(".contents").unmark({ 40 | done: function() { 41 | $(".contents").mark(keyword); 42 | } 43 | }); 44 | } 45 | } 46 | }; 47 | 48 | mark(); 49 | }); 50 | }); 51 | 52 | /* Search term highlighting ------------------------------*/ 53 | 54 | function matchedWords(hit) { 55 | var words = []; 56 | 57 | var hierarchy = hit._highlightResult.hierarchy; 58 | // loop to fetch from lvl0, lvl1, etc. 59 | for (var idx in hierarchy) { 60 | words = words.concat(hierarchy[idx].matchedWords); 61 | } 62 | 63 | var content = hit._highlightResult.content; 64 | if (content) { 65 | words = words.concat(content.matchedWords); 66 | } 67 | 68 | // return unique words 69 | var words_uniq = [...new Set(words)]; 70 | return words_uniq; 71 | } 72 | 73 | function updateHitURL(hit) { 74 | 75 | var words = matchedWords(hit); 76 | var url = ""; 77 | 78 | if (hit.anchor) { 79 | url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; 80 | } else { 81 | url = hit.url + '?q=' + escape(words.join(" ")); 82 | } 83 | 84 | return url; 85 | } 86 | -------------------------------------------------------------------------------- /R/get_aggregation_any.R: -------------------------------------------------------------------------------- 1 | get_aggregation.any <- function(plot_width, plot_height, aesthetics, 2 | x_range, y_range, xlim, ylim, 3 | func, glyph, group_by_data_table, ...) { 4 | 5 | is_on <- !is.null(aesthetics$on) 6 | is_size <- !is.null(aesthetics$size) 7 | is_color <- !is.null(aesthetics$color) 8 | 9 | L <- if(group_by_data_table) { 10 | 11 | display <- aesthetics[, 12 | list( 13 | display = list( 14 | aggregation_anyCpp(plot_width = plot_width, plot_height = plot_height, 15 | x_range = x_range, y_range = y_range, 16 | xlim = xlim, ylim = ylim, 17 | x = x, 18 | y = y, 19 | on = if(is_on) on else numeric(0), 20 | size = if(is_size) size else numeric(0), 21 | glyph = glyph) 22 | ) 23 | ), 24 | by = if(is_color) color else NULL] 25 | remove(aesthetics) 26 | display$display 27 | } else { 28 | if(is_color) { 29 | levels <- unique(aesthetics$color) 30 | # agg_sumCpp return a list 31 | agg_anyCpp(L = lapply(1:length(levels), function(i) matrix(0, nrow = plot_height, ncol = plot_width)), 32 | levels = levels, 33 | category = aesthetics$color, 34 | plot_width = plot_width, plot_height = plot_height, 35 | x_range = x_range, y_range = y_range, 36 | xlim = xlim, ylim = ylim, 37 | x = aesthetics$x, 38 | y = aesthetics$y, 39 | on = if(is_on) aesthetics$on else numeric(0), 40 | size = if(is_size) aesthetics$size else numeric(0), 41 | glyph = glyph) 42 | } else { 43 | list( 44 | aggregation_anyCpp(plot_width = plot_width, plot_height = plot_height, 45 | x_range = x_range, y_range = y_range, 46 | xlim = xlim, ylim = ylim, 47 | x = aesthetics$x, 48 | y = aesthetics$y, 49 | on = if(is_on) aesthetics$on else numeric(0), 50 | size = if(is_size) aesthetics$size else numeric(0), 51 | glyph = glyph) 52 | ) 53 | } 54 | } 55 | return(L) 56 | } 57 | -------------------------------------------------------------------------------- /R/get_aggregation_max.R: -------------------------------------------------------------------------------- 1 | get_aggregation.max <- function(plot_width, plot_height, aesthetics, 2 | x_range, y_range, xlim, ylim, 3 | func, glyph, group_by_data_table, ...) { 4 | 5 | if(is.null(aesthetics$on)) stop("No `on` argument was provided. Which variable should be used when calculating the maximum value for aggregation?") 6 | is_size <- !is.null(aesthetics$size) 7 | is_color <- !is.null(aesthetics$color) 8 | 9 | L <- if(group_by_data_table) { 10 | 11 | display <- aesthetics[, 12 | list( 13 | display = list( 14 | aggregation_maxCpp(plot_width = plot_width, plot_height = plot_height, 15 | x_range = x_range, y_range = y_range, 16 | xlim = xlim, ylim = ylim, 17 | x = x, 18 | y = y, 19 | on = on, 20 | size = if(is_size) size else numeric(0), 21 | glyph = glyph) 22 | ) 23 | ), 24 | by = if(is_color) color else NULL] 25 | remove(aesthetics) 26 | display$display 27 | } else { 28 | 29 | if(is_color) { 30 | levels <- unique(aesthetics$color) 31 | # agg_sumCpp return a list 32 | agg_maxCpp(L = lapply(1:length(levels), function(i) matrix(0, nrow = plot_height, ncol = plot_width)), 33 | levels = levels, 34 | category = aesthetics$color, 35 | plot_width = plot_width, plot_height = plot_height, 36 | x_range = x_range, y_range = y_range, 37 | xlim = xlim, ylim = ylim, 38 | x = aesthetics$x, 39 | y = aesthetics$y, 40 | on = aesthetics$on, 41 | size = if(is_size) aesthetics$size else numeric(0), 42 | glyph = glyph) 43 | } else { 44 | list( 45 | aggregation_maxCpp(plot_width = plot_width, plot_height = plot_height, 46 | x_range = x_range, y_range = y_range, 47 | xlim = xlim, ylim = ylim, 48 | x = aesthetics$x, 49 | y = aesthetics$y, 50 | on = aesthetics$on, 51 | size = if(is_size) aesthetics$size else numeric(0), 52 | glyph = glyph) 53 | ) 54 | } 55 | } 56 | return(L) 57 | } 58 | -------------------------------------------------------------------------------- /R/get_aggregation_min.R: -------------------------------------------------------------------------------- 1 | get_aggregation.min <- function(plot_width, plot_height, aesthetics, 2 | x_range, y_range, xlim, ylim, 3 | func, glyph, group_by_data_table, ...) { 4 | 5 | if(is.null(aesthetics$on)) stop("No `on` argument was provided. Which variable should be used when calculating the minimum value for aggregation?") 6 | is_size <- !is.null(aesthetics$size) 7 | is_color <- !is.null(aesthetics$color) 8 | 9 | L <- if(group_by_data_table) { 10 | 11 | display <- aesthetics[, 12 | list( 13 | display = list( 14 | aggregation_minCpp(plot_width = plot_width, plot_height = plot_height, 15 | x_range = x_range, y_range = y_range, 16 | xlim = xlim, ylim = ylim, 17 | x = x, 18 | y = y, 19 | on = on, 20 | size = if(is_size) size else numeric(0), 21 | glyph = glyph) 22 | ) 23 | ), 24 | by = if(is_color) color else NULL] 25 | remove(aesthetics) 26 | display$display 27 | } else { 28 | 29 | if(is_color) { 30 | levels <- unique(aesthetics$color) 31 | # agg_sumCpp return a list 32 | agg_minCpp(L = lapply(1:length(levels), function(i) matrix(0, nrow = plot_height, ncol = plot_width)), 33 | levels = levels, 34 | category = aesthetics$color, 35 | plot_width = plot_width, plot_height = plot_height, 36 | x_range = x_range, y_range = y_range, 37 | xlim = xlim, ylim = ylim, 38 | x = aesthetics$x, 39 | y = aesthetics$y, 40 | on = aesthetics$on, 41 | size = if(is_size) aesthetics$size else numeric(0), 42 | glyph = glyph) 43 | } else { 44 | list( 45 | aggregation_minCpp(plot_width = plot_width, plot_height = plot_height, 46 | x_range = x_range, y_range = y_range, 47 | xlim = xlim, ylim = ylim, 48 | x = aesthetics$x, 49 | y = aesthetics$y, 50 | on = aesthetics$on, 51 | size = if(is_size) aesthetics$size else numeric(0), 52 | glyph = glyph) 53 | ) 54 | } 55 | } 56 | return(L) 57 | } 58 | -------------------------------------------------------------------------------- /R/extract.R: -------------------------------------------------------------------------------- 1 | #' @title Extract or replace parts of a \code{rasterly} object 2 | #' @name extract 3 | #' @description The \code{extract} function provides functionality for updating existing \code{rasterly} objects. 4 | #' @param x Object from which to extract element(s) or in which to replace element(s). 5 | #' @param name Character. A literal string to be extracted from \code{x}. See details for more information. 6 | #' 7 | #' @details Available names: 8 | #' \itemize{ 9 | #' \item{Aggregation: }{"data", "mapping", "plot_width", "plot_height", "range", "x_range", 10 | #' "y_range", "xlim", "ylim", "aesthetics", "reduction_func", "glyph", 11 | #' "max_size", "group_by_data_table", "drop_data", "variable_check"} 12 | #' \item{Display: }{"background", "color", "alpha", "span", 13 | #' "show_raster", "layout"} 14 | #' } 15 | #' 16 | #' @examples 17 | #' library(rasterly) 18 | #' r <- rasterly( 19 | #' data = data.frame(x = 1:1e4, y = runif(1e4), category = sample(1:4, 1e4, replace = TRUE)), 20 | #' mapping = aes(x = x, y = y) 21 | #' ) %>% 22 | #' rasterly_points(xlim = c(1, 5000)) %>% 23 | #' rasterly_points( 24 | #' mapping = aes(x = x, y = y, color = category), 25 | #' xlim = c(5001, 1e4) 26 | #' ) 27 | #' r["mapping"] 28 | #' r["xlim"] 29 | #' 30 | #' # reassign parent `rasterly()` mapping 31 | #' r["mapping"] <- aes(x = x, y = y, color = category) 32 | #' r["mapping"] 33 | #' 34 | #' # reassign all mapping systems 35 | #' r["mapping", level = 1:length(r)] <- aes(x = x, y = y) 36 | #' r["mapping"] 37 | #' @export 38 | `[.rasterly` <- function(x, name) { 39 | # x is executed 40 | if(is.rasterlyBuild(x)) { 41 | getElement(x, name) 42 | } else { 43 | # x is an unexecuted list of environments 44 | lapply(x, 45 | function(envir) { 46 | .get(name, envir = envir) 47 | }) 48 | } 49 | } 50 | 51 | #' @param ... (missing) or NULL. 52 | #' @param value values to replace; typically an array-like R object of a similar class as x. 53 | #' @rdname extract 54 | #' @details 55 | #' Set \code{level} in \code{...}. \code{level} is numeric used for specifing level of `rasterly` object to modify; 56 | #' default is 1 for the parent layer (\code{rasterly()}). 57 | #' 58 | #' @export 59 | `[<-.rasterly` <- function(x, name, ..., value) { 60 | 61 | args <- list(...) 62 | level <- args$level %||% 1 63 | 64 | # x is executed 65 | if(is.rasterlyBuild(x)) { 66 | warning("Replacing elements of existing `rasterlyBuild` objects is not supported.", call. = FALSE) 67 | do.call(`$<-`, list(x = x, name = name, value = value)) 68 | } else { 69 | # x is an unexecuted list of environments 70 | for(l in level) { 71 | assign(name, value, envir = x[[l]]) 72 | } 73 | invisible(return(x)) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /R/get_aggregation_last.R: -------------------------------------------------------------------------------- 1 | get_aggregation.last <- function(plot_width, plot_height, aesthetics, 2 | x_range, y_range, xlim, ylim, 3 | func, glyph, group_by_data_table, ...) { 4 | 5 | if(is.null(aesthetics$on)) stop("No `on` argument was provided. Which variable should be used to specify the last value encountered for aggregation?") 6 | is_size <- !is.null(aesthetics$size) 7 | is_color <- !is.null(aesthetics$color) 8 | 9 | L <- if(group_by_data_table) { 10 | 11 | display <- aesthetics[, 12 | list( 13 | display = list( 14 | aggregation_lastCpp(plot_width = plot_width, plot_height = plot_height, 15 | x_range = x_range, y_range = y_range, 16 | xlim = xlim, ylim = ylim, 17 | x = x, 18 | y = y, 19 | on = on, 20 | size = if(is_size) size else numeric(0), 21 | glyph = glyph) 22 | ) 23 | ), 24 | by = if(is_color) color else NULL] 25 | remove(aesthetics) 26 | display$display 27 | } else { 28 | 29 | if(is_color) { 30 | levels <- unique(aesthetics$color) 31 | # agg_sumCpp return a list 32 | agg_lastCpp(L = lapply(1:length(levels), function(i) matrix(0, nrow = plot_height, ncol = plot_width)), 33 | levels = levels, 34 | category = aesthetics$color, 35 | plot_width = plot_width, plot_height = plot_height, 36 | x_range = x_range, y_range = y_range, 37 | xlim = xlim, ylim = ylim, 38 | x = aesthetics$x, 39 | y = aesthetics$y, 40 | on = aesthetics$on, 41 | size = if(is_size) aesthetics$size else numeric(0), 42 | glyph = glyph) 43 | } else { 44 | list( 45 | aggregation_lastCpp(plot_width = plot_width, plot_height = plot_height, 46 | x_range = x_range, y_range = y_range, 47 | xlim = xlim, ylim = ylim, 48 | x = aesthetics$x, 49 | y = aesthetics$y, 50 | on = aesthetics$on, 51 | size = if(is_size) aesthetics$size else numeric(0), 52 | glyph = glyph) 53 | ) 54 | } 55 | } 56 | return(L) 57 | } 58 | -------------------------------------------------------------------------------- /R/get_aggregation_first.R: -------------------------------------------------------------------------------- 1 | get_aggregation.first <- function(plot_width, plot_height, aesthetics, 2 | x_range, y_range, xlim, ylim, 3 | func, glyph, group_by_data_table, ...) { 4 | 5 | 6 | if(is.null(aesthetics$on)) stop("No `on` argument was provided. Which variable should be used to return the first value encountered for aggregation?") 7 | is_size <- !is.null(aesthetics$size) 8 | is_color <- !is.null(aesthetics$color) 9 | 10 | L <- if(group_by_data_table) { 11 | 12 | display <- aesthetics[, 13 | list( 14 | display = list( 15 | aggregation_firstCpp(plot_width = plot_width, plot_height = plot_height, 16 | x_range = x_range, y_range = y_range, 17 | xlim = xlim, ylim = ylim, 18 | x = x, 19 | y = y, 20 | on = on, 21 | size = if(is_size) size else numeric(0), 22 | glyph = glyph) 23 | ) 24 | ), 25 | by = if(is_color) color else NULL] 26 | remove(aesthetics) 27 | display$display 28 | } else { 29 | 30 | if(is_color) { 31 | levels <- unique(aesthetics$color) 32 | # agg_sumCpp return a list 33 | agg_firstCpp(L = lapply(1:length(levels), function(i) matrix(0, nrow = plot_height, ncol = plot_width)), 34 | levels = levels, 35 | category = aesthetics$color, 36 | plot_width = plot_width, plot_height = plot_height, 37 | x_range = x_range, y_range = y_range, 38 | xlim = xlim, ylim = ylim, 39 | x = aesthetics$x, 40 | y = aesthetics$y, 41 | on = aesthetics$on, 42 | size = if(is_size) aesthetics$size else numeric(0), 43 | glyph = glyph) 44 | } else { 45 | list( 46 | aggregation_firstCpp(plot_width = plot_width, plot_height = plot_height, 47 | x_range = x_range, y_range = y_range, 48 | xlim = xlim, ylim = ylim, 49 | x = aesthetics$x, 50 | y = aesthetics$y, 51 | on = aesthetics$on, 52 | size = if(is_size) aesthetics$size else numeric(0), 53 | glyph = glyph) 54 | ) 55 | } 56 | } 57 | return(L) 58 | } 59 | -------------------------------------------------------------------------------- /R/get_aggregation_sum.R: -------------------------------------------------------------------------------- 1 | get_aggregation <- function(plot_width, plot_height, aesthetics, 2 | x_range, y_range, xlim, ylim, func, glyph, group_by_data_table, ...) { 3 | UseMethod("get_aggregation", func) 4 | } 5 | 6 | get_aggregation.sum <- function(plot_width, plot_height, aesthetics, 7 | x_range, y_range, xlim, ylim, 8 | func, glyph, group_by_data_table, ...) { 9 | 10 | is_on <- !is.null(aesthetics$on) 11 | is_size <- !is.null(aesthetics$size) 12 | is_color <- !is.null(aesthetics$color) 13 | 14 | L <- if(group_by_data_table) { 15 | 16 | display <- aesthetics[, 17 | list( 18 | display = list( 19 | aggregation_sumCpp(plot_width = plot_width, plot_height = plot_height, 20 | x_range = x_range, y_range = y_range, 21 | xlim = xlim, ylim = ylim, 22 | x = x, 23 | y = y, 24 | on = if(is_on) on else numeric(0), 25 | size = if(is_size) size else numeric(0), 26 | glyph = glyph) 27 | ) 28 | ), 29 | by = if(is_color) color else NULL] 30 | remove(aesthetics) 31 | display$display 32 | } else { 33 | 34 | if(is_color) { 35 | levels <- unique(aesthetics$color) 36 | # agg_sumCpp return a list 37 | agg_sumCpp(L = lapply(1:length(levels), function(i) matrix(0, nrow = plot_height, ncol = plot_width)), 38 | levels = levels, 39 | category = aesthetics$color, 40 | plot_width = plot_width, plot_height = plot_height, 41 | x_range = x_range, y_range = y_range, 42 | xlim = xlim, ylim = ylim, 43 | x = aesthetics$x, 44 | y = aesthetics$y, 45 | on = if(is_on) aesthetics$on else numeric(0), 46 | size = if(is_size) aesthetics$size else numeric(0), 47 | glyph = glyph) 48 | } else { 49 | list( 50 | aggregation_sumCpp(plot_width = plot_width, plot_height = plot_height, 51 | x_range = x_range, y_range = y_range, 52 | xlim = xlim, ylim = ylim, 53 | x = aesthetics$x, 54 | y = aesthetics$y, 55 | on = if(is_on) aesthetics$on else numeric(0), 56 | size = if(is_size) aesthetics$size else numeric(0), 57 | glyph = glyph) 58 | ) 59 | } 60 | } 61 | 62 | return(L) 63 | } 64 | -------------------------------------------------------------------------------- /man/rasterize_points.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rasterize_points.R 3 | \name{rasterize_points} 4 | \alias{rasterize_points} 5 | \title{rasterize_points} 6 | \usage{ 7 | rasterize_points( 8 | rastObj, 9 | data = NULL, 10 | mapping = aes(), 11 | ..., 12 | xlim = NULL, 13 | ylim = NULL, 14 | max_size = NULL, 15 | reduction_func = NULL, 16 | layout = NULL, 17 | glyph = NULL, 18 | group_by_data_table = NULL, 19 | inherit.aes = TRUE 20 | ) 21 | } 22 | \arguments{ 23 | \item{rastObj}{A \code{rasterly} object.} 24 | 25 | \item{data}{A \code{data.frame} or \code{function} with an argument \code{x}, specifying the dataset to use for plotting. If \code{data} 26 | is \code{NULL}, the \code{data} argument provided to \code{rasterly} may be passed through.} 27 | 28 | \item{mapping}{Default list of aesthetic mappings to use for plot. If provided and \code{inherit.aes = TRUE}, it will be 29 | stacked on top of the mappings passed to \code{rasterly}.} 30 | 31 | \item{...}{Pass-through arguments provided by \code{rasterly}.} 32 | 33 | \item{xlim}{Vector of type numeric. X limits in this layer.} 34 | 35 | \item{ylim}{Vector of type numeric. Y limits in this layer.} 36 | 37 | \item{max_size}{Numeric. When size changes, the upper bound of the number of pixels over which to spread a single observation.} 38 | 39 | \item{reduction_func}{Function. A reduction function is used to aggregate data points into their pixel representations. Currently 40 | supported reduction operators are \code{sum}, \code{any}, \code{mean}, \code{m2}, \code{first}, \code{last}, \code{min} and \code{max}. Default is \code{sum}. See details.} 41 | 42 | \item{layout}{Character. The method used to generate layouts for multiple images. The default is \code{weighted}. Useful for categorical 43 | data (i.e. "color" is provided via \code{aes()}). \code{weighted} specifies that the final raster should be a weighted combination of each 44 | (categorical) aggregation matrix. Conversely, \code{cover} indicates that the afterwards objects will be drawn on top of 45 | the previous ones.} 46 | 47 | \item{glyph}{Character. Currently, only "circle" and "square" are supported; as the \code{size} of the pixels increases, how should they 48 | spread out -- should the pattern be circular or square? Other glyphs may be added in the future.} 49 | 50 | \item{group_by_data_table}{Logical. Default is \code{TRUE}; when "color" is provided via \code{aes()}, the "group by" operation may be 51 | perfromed within \code{data.table} or natively within \code{rasterly}. Generally, \code{group_by_data_table = TRUE} is faster, but for very 52 | large datasets grouping within \code{rasterly} may offer better performance.} 53 | 54 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, rather than combining with them.} 55 | } 56 | \description{ 57 | Points layer for "rasterly". Deprecated now, please use \code{rasterly_points} instead. 58 | } 59 | \seealso{ 60 | \link{rasterly_points} 61 | } 62 | -------------------------------------------------------------------------------- /R/image2data.R: -------------------------------------------------------------------------------- 1 | #' @title Image raster to data frame. 2 | #' @description Transform a image raster to a data frame. 3 | #' @param x It could be a rasterly object or a raster image. 4 | #' @param background The background of image raster. 5 | #' @param x_range The range represents image width. 6 | #' @param y_range The range represents image height. 7 | #' @return a \code{data.table} object 8 | #' @seealso \link{ggRasterly} 9 | #' @examples 10 | #' x <- rnorm(1000, mean = 10) 11 | #' y <- rnorm(1000, mean = 20) 12 | #' color <- sample(1:5, 1000, replace = TRUE) 13 | #' rastObj <- data.frame(x = x, y = y, color = color) %>% 14 | #' rasterly(mapping = aes(x = x, y = y, color = color)) %>% 15 | #' rasterly_points() 16 | #' p <- rasterly_build(rastObj) 17 | #' dt <- image2data(p) 18 | #' if(requireNamespace("ggplot2")) { 19 | #' # Note that each point represents a single pixel in the image 20 | #' ggplot2::ggplot(dt, mapping = aes(x = x, y = y)) + 21 | #' ggplot2::geom_point(color = dt$color, size = 0.5) 22 | #' } 23 | #' @export 24 | image2data <- function(x, 25 | background = "white", 26 | x_range = NULL, 27 | y_range = NULL) { 28 | if(missing(x)) stop("Missing x") 29 | UseMethod("image2data", x) 30 | } 31 | 32 | #' @export 33 | image2data.rasterly <- function(x, 34 | background = "white", 35 | x_range = NULL, 36 | y_range = NULL) { 37 | 38 | if(!is.rasterlyBuild(x)) x <- rasterly_build(x) 39 | 40 | imageData(image = as.matrix(x$image), 41 | background = background %||% x$background, 42 | x_range = x_range %||% x$x_range, 43 | y_range = y_range %||% x$y_range) 44 | } 45 | 46 | #' @export 47 | image2data.raster <- function(x, 48 | background = "white", 49 | x_range = NULL, 50 | y_range = NULL) { 51 | imageData(image = as.matrix(x), 52 | background = background, 53 | x_range = x_range, 54 | y_range = y_range) 55 | } 56 | 57 | #' @export 58 | image2data.matrix <- function(x, 59 | background = "white", 60 | x_range = NULL, 61 | y_range = NULL) { 62 | 63 | imageData(image = x, 64 | background = background, 65 | x_range = x_range, 66 | y_range = y_range) 67 | } 68 | 69 | imageData <- function(image, 70 | background = "white", 71 | x_range = NULL, 72 | y_range = NULL) { 73 | dimM <- dim(image) 74 | height <- dimM[1] 75 | width <- dimM[2] 76 | 77 | x_range <- x_range %||% c(1, width) 78 | y_range <- y_range %||% c(1, height) 79 | 80 | y <- rep(seq(from = y_range[2], to = y_range[1], length.out = height), width) 81 | x <- rep(seq(from = x_range[1], to = x_range[2], length.out = width), each = height) 82 | 83 | not_blank_id <- c(!image %in% background) 84 | y <- y[not_blank_id] 85 | x <- x[not_blank_id] 86 | image <- image[not_blank_id] 87 | data.table::data.table( 88 | x = x, 89 | y = y, 90 | color = image 91 | ) 92 | } -------------------------------------------------------------------------------- /R/add_rasterly_image.R: -------------------------------------------------------------------------------- 1 | #' @param color Numeric vector or expression. Pixel color for each observation, to be passed on to \code{aes()}. 2 | #' @rdname add_rasterly 3 | #' @export 4 | 5 | add_rasterly_image <- function(p, 6 | x = NULL, y = NULL, z = NULL, ..., 7 | data = NULL, inherit = TRUE, 8 | color = NULL, on = NULL, size = NULL) { 9 | if (inherit) { 10 | x <- x %||% p$x$attrs[[1]][["x"]] 11 | y <- y %||% p$x$attrs[[1]][["y"]] 12 | z <- z %||% p$x$attrs[[1]][["z"]] 13 | } 14 | 15 | args <- list(...) 16 | rasterly_args <- c( 17 | union(methods::formalArgs(rasterly), methods::formalArgs(rasterly_points)), 18 | "color_map", 19 | "colour_map", 20 | "color_key", 21 | "colour_key" 22 | ) 23 | args[rasterly_args] <- NULL 24 | 25 | if (is.null(z)) { 26 | # produce z by rasterly 27 | ### set vars 28 | data <- data %||% p$x$visdat[[1]]() 29 | on <- on %||% p$x$attrs[[1]][["on"]] 30 | size <- size %||% p$x$attrs[[1]][["size"]] 31 | color <- color %||% p$x$attrs[[1]][["color"]] 32 | 33 | ### set mappings 34 | mapping_names <- c("x", "y", "on", "size", "color") 35 | names(mapping_names) <- mapping_names 36 | mapping <- aes() 37 | expressions <- stats::setNames( 38 | list(x, y, on, size, color), 39 | mapping_names 40 | ) 41 | 42 | for(i in 1:length(mapping_names)) { 43 | exp <- expressions[[i]] 44 | 45 | if(is.null(exp)) { 46 | mapping_names[i] <- NA 47 | } else { 48 | if(rlang::is_formula(exp)) { 49 | the_parse <- sub("~", "", rlang::expr_text(exp)) %>% 50 | rlang::parse_expr() 51 | mapping[[i]] <- rlang::quo(!!the_parse) 52 | } else if(is.numeric(exp)) { 53 | data[[mapping_names[i]]] <- exp 54 | mapping[[i]] <- rlang::quo(!!rlang::parse_expr(mapping_names[i])) 55 | } else { 56 | stop("'size' ,'on' and 'color' are neither `quote` nor a numerical value.", call. = FALSE) 57 | } 58 | } 59 | } 60 | 61 | mapping <- Filter(Negate(is.null), mapping) 62 | names(mapping) <- stats::na.omit(mapping_names) 63 | 64 | data %>% 65 | rasterly(mapping = mapping, 66 | show_raster = TRUE, 67 | ...) %>% 68 | rasterly_points() %>% 69 | rasterly_build() -> rastObj 70 | data <- NULL 71 | 72 | z <- rastObj$image 73 | dimZ <- dim(z) 74 | 75 | do.call( 76 | plotly::add_image, 77 | c( 78 | list( 79 | p = p, 80 | z = z, 81 | x0 = rastObj$x_range[1], 82 | dx = diff(rastObj$x_range)/dimZ[2], 83 | y0 = rastObj$y_range[2], 84 | dy = -diff(rastObj$y_range)/dimZ[1], 85 | data = data, 86 | inherit = inherit 87 | ), 88 | args 89 | ) 90 | ) %>% plotly::layout( 91 | xaxis = list(range = rastObj$x_range), 92 | yaxis = list(range = rastObj$y_range) 93 | ) 94 | 95 | } else { 96 | message("If z is provided, `plotly::add_image` will be implemented.") 97 | do.call( 98 | plotly::add_image, 99 | c( 100 | list( 101 | p = p, 102 | z = z, 103 | data = data, 104 | inherit = inherit 105 | ), 106 | args 107 | ) 108 | ) 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | # it is equivalent to R.utils::isZero 2 | isZero <- function (x, neps = 1, eps = .Machine$double.eps, ...) { 3 | if (is.character(eps)) { 4 | eps <- match.arg(eps, choices = c("double.eps", "single.eps")) 5 | if (eps == "double.eps") { 6 | eps <- .Machine$double.eps 7 | } 8 | else if (eps == "single.eps") { 9 | eps <- sqrt(.Machine$double.eps) 10 | } 11 | } 12 | (abs(x) < neps * eps) 13 | } 14 | 15 | 16 | mbind <- function(new_mapping = aes(), mapping) { 17 | 18 | if (!missing(mapping) && !inherits(mapping, "uneval") && 19 | !missing(new_mapping) && !inherits(new_mapping, "uneval")) { 20 | stop("Mapping should be created with `aes()`.", call. = FALSE) 21 | } 22 | 23 | new_aes(new_mapping %<-% mapping) 24 | } 25 | 26 | .get <- function(x, envir = as.environment(-1), mode = "any", ifnotfound, 27 | inherits = FALSE) { 28 | 29 | if(missing(ifnotfound)) 30 | ifnotfound <- list(NULL) 31 | 32 | mget(x = x, envir = envir, mode = mode, 33 | ifnotfound = ifnotfound, 34 | inherits = inherits)[[x]] 35 | 36 | } 37 | 38 | 39 | get_cdf <- function(M, zeroIgnored = TRUE, ...) { 40 | 41 | if(missing(M)) stop("No matrix found; get_cdf requires a valid matrix M is passed.") 42 | args <- list(...) 43 | 44 | cdf <- if(zeroIgnored) { 45 | 46 | which_is_not_zero <- if(!is.null(args$which_is_not_zero)) args$which_is_not_zero else M != 0 47 | stats::ecdf(M[which_is_not_zero]) 48 | } else { 49 | stats::ecdf(M) 50 | } 51 | 52 | return(cdf) 53 | } 54 | 55 | color_warning <- function(envir, args) { 56 | 57 | color_key <- .get("color_key", envir = envir) 58 | color_map <- .get("color_map", envir = envir) 59 | 60 | if(is.null(color_key) && is.null(color_map)) { 61 | 62 | if(!is.null(args$color_key)) 63 | warning("`color_key` is deprecated now. Please use `color` instead.", call. = FALSE) 64 | 65 | if(!is.null(args$color_map)) 66 | warning("`color_map` is deprecated now. Please use `color` instead.", call. = FALSE) 67 | 68 | } else NULL # warning has already been generated 69 | } 70 | 71 | get_varnames <- function(var_names, dir) { 72 | varnames <- switch(dir, 73 | "x" = var_names[grepl("x", names(var_names))][1], 74 | "y" = var_names[grepl("y", names(var_names))][1] 75 | ) 76 | return(varnames) 77 | } 78 | 79 | 80 | remove_missing_matrix <- function(m, value = 0) { 81 | m[!rowSums(!is.finite(m)),] 82 | # replace all non-finite values with 0 83 | m[!is.finite(m)] <- value 84 | m 85 | } 86 | 87 | rename_mapping <- function(mapping) { 88 | 89 | if (!missing(mapping) && !inherits(mapping, "uneval")) { 90 | stop("Mapping should be created with `aes()`.", call. = FALSE) 91 | } 92 | 93 | names_mapping <- names(mapping) 94 | if(length(names_mapping) == 0 || !"colour" %in% names_mapping) return(mapping) 95 | names_mapping[names_mapping == "colour"] <- "color" 96 | names(mapping) <- names_mapping 97 | return(mapping) 98 | } 99 | 100 | # Pass R CMD check --as-cran 101 | # Suggestion from https://stackoverflow.com/questions/9439256/how-can-i-handle-r-cmd-check-no-visible-binding-for-global-variable-notes-when 102 | # The reason to set globalVariables instead of define x, y, ... is because 103 | # the cost of extraction values from large data is very heavy 104 | if(getRversion() >= "3.1.0") utils::globalVariables(c("..mapping_names", "size", "x", "y", "on", "color", ".")) 105 | -------------------------------------------------------------------------------- /man/rplot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rplot.R 3 | \name{rplot} 4 | \alias{rplot} 5 | \alias{rplot.default} 6 | \title{Rasterly plot} 7 | \usage{ 8 | rplot(x, y = NULL, ...) 9 | 10 | \method{rplot}{default}( 11 | x, 12 | y = NULL, 13 | ..., 14 | plot_width = 600, 15 | plot_height = 600, 16 | x_range = NULL, 17 | y_range = NULL, 18 | background = "white", 19 | reduction_func = NULL, 20 | layout = NULL, 21 | glyph = NULL 22 | ) 23 | } 24 | \arguments{ 25 | \item{x, y}{Coordinates x, y for the plot.} 26 | 27 | \item{...}{Other \code{rasterly} arguments to pass through.} 28 | 29 | \item{plot_width}{Integer. The width of the image to plot; must be a positive integer. A higher value indicates a higher resolution.} 30 | 31 | \item{plot_height}{Integer. The height of the image to plot; must be a positive integer. A higher value indicates a higher resolution.} 32 | 33 | \item{x_range}{Vector of type numeric. The range of \code{x}; it can be used to clip the image. For larger datasets, providing \code{x_range} 34 | may result in improved performance.} 35 | 36 | \item{y_range}{Vector of type numeric. The range of \code{y}; it can be used to clip the image. For larger datasets, providing \code{y_range} 37 | may result in improved performance.} 38 | 39 | \item{background}{Character. The background color of the image to plot.} 40 | 41 | \item{reduction_func}{Function. A reduction function is used to aggregate data points into their pixel representations. Currently 42 | supported reduction operators are \code{sum}, \code{any}, \code{mean}, \code{m2}, \code{first}, \code{last}, \code{min} and \code{max}. Default is \code{sum}. See details.} 43 | 44 | \item{layout}{Character. The method used to generate layouts for multiple images. The default is \code{weighted}. Useful for categorical 45 | data (i.e. "color" is provided via \code{aes()}). \code{weighted} specifies that the final raster should be a weighted combination of each 46 | (categorical) aggregation matrix. Conversely, \code{cover} indicates that the afterwards objects will be drawn on top of 47 | the previous ones.} 48 | 49 | \item{glyph}{Character. Currently, only "circle" and "square" are supported; as the \code{size} of the pixels increases, how should they 50 | spread out -- should the pattern be circular or square? Other glyphs may be added in the future.} 51 | } 52 | \description{ 53 | \code{rplot} is created to generate \code{rasterly} plot quickly but with base 54 | \link{plot} design. It is convenient but lacks flexibility and \link{rasterly} is highly 55 | recommended for a more versatile method. 56 | } 57 | \details{ 58 | \code{rasterly} arguments are passed through via \code{...}. But some of them are noticeable. 59 | \itemize{ 60 | \item{\code{size}: Size can be either a specified size (1, 2, 3, etc) or a mapping variable. Since \code{rasterly} does not provide 61 | point to point display, if the length of input \code{size} is the same with the length of \code{x} (or \code{y}). It will be treated as 62 | a mapping variable.} 63 | \item{\code{color}: Color can be either a color map vector or a mapping variable. If the length of \code{color} is equal to the length of 64 | \code{x} (or \code{y}). It will be treated as a mapping variable.} 65 | \item{\code{on}: On is always treated as a mapping variable.} 66 | } 67 | } 68 | \examples{ 69 | if(requireNamespace("ggplot2")) { 70 | library(ggplot2) 71 | # `color` represents a variable here 72 | with(diamonds, 73 | rplot(x = carat, y = price, color = color) 74 | ) 75 | # `color` represents an actual color vector 76 | with(diamonds, 77 | rplot(x = carat, y = price, color = fire_map) 78 | ) 79 | } 80 | } 81 | \seealso{ 82 | \link{rasterly} \link{rasterly_points} 83 | } 84 | -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | /* http://gregfranko.com/blog/jquery-best-practices/ */ 2 | (function($) { 3 | $(function() { 4 | 5 | $('.navbar-fixed-top').headroom(); 6 | 7 | $('body').css('padding-top', $('.navbar').height() + 10); 8 | $(window).resize(function(){ 9 | $('body').css('padding-top', $('.navbar').height() + 10); 10 | }); 11 | 12 | $('body').scrollspy({ 13 | target: '#sidebar', 14 | offset: 60 15 | }); 16 | 17 | $('[data-toggle="tooltip"]').tooltip(); 18 | 19 | var cur_path = paths(location.pathname); 20 | var links = $("#navbar ul li a"); 21 | var max_length = -1; 22 | var pos = -1; 23 | for (var i = 0; i < links.length; i++) { 24 | if (links[i].getAttribute("href") === "#") 25 | continue; 26 | // Ignore external links 27 | if (links[i].host !== location.host) 28 | continue; 29 | 30 | var nav_path = paths(links[i].pathname); 31 | 32 | var length = prefix_length(nav_path, cur_path); 33 | if (length > max_length) { 34 | max_length = length; 35 | pos = i; 36 | } 37 | } 38 | 39 | // Add class to parent
  • , and enclosing
  • if in dropdown 40 | if (pos >= 0) { 41 | var menu_anchor = $(links[pos]); 42 | menu_anchor.parent().addClass("active"); 43 | menu_anchor.closest("li.dropdown").addClass("active"); 44 | } 45 | }); 46 | 47 | function paths(pathname) { 48 | var pieces = pathname.split("/"); 49 | pieces.shift(); // always starts with / 50 | 51 | var end = pieces[pieces.length - 1]; 52 | if (end === "index.html" || end === "") 53 | pieces.pop(); 54 | return(pieces); 55 | } 56 | 57 | // Returns -1 if not found 58 | function prefix_length(needle, haystack) { 59 | if (needle.length > haystack.length) 60 | return(-1); 61 | 62 | // Special case for length-0 haystack, since for loop won't run 63 | if (haystack.length === 0) { 64 | return(needle.length === 0 ? 0 : -1); 65 | } 66 | 67 | for (var i = 0; i < haystack.length; i++) { 68 | if (needle[i] != haystack[i]) 69 | return(i); 70 | } 71 | 72 | return(haystack.length); 73 | } 74 | 75 | /* Clipboard --------------------------*/ 76 | 77 | function changeTooltipMessage(element, msg) { 78 | var tooltipOriginalTitle=element.getAttribute('data-original-title'); 79 | element.setAttribute('data-original-title', msg); 80 | $(element).tooltip('show'); 81 | element.setAttribute('data-original-title', tooltipOriginalTitle); 82 | } 83 | 84 | if(ClipboardJS.isSupported()) { 85 | $(document).ready(function() { 86 | var copyButton = ""; 87 | 88 | $(".examples, div.sourceCode").addClass("hasCopyButton"); 89 | 90 | // Insert copy buttons: 91 | $(copyButton).prependTo(".hasCopyButton"); 92 | 93 | // Initialize tooltips: 94 | $('.btn-copy-ex').tooltip({container: 'body'}); 95 | 96 | // Initialize clipboard: 97 | var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { 98 | text: function(trigger) { 99 | return trigger.parentNode.textContent; 100 | } 101 | }); 102 | 103 | clipboardBtnCopies.on('success', function(e) { 104 | changeTooltipMessage(e.trigger, 'Copied!'); 105 | e.clearSelection(); 106 | }); 107 | 108 | clipboardBtnCopies.on('error', function() { 109 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); 110 | }); 111 | }); 112 | } 113 | })(window.jQuery || window.$) 114 | -------------------------------------------------------------------------------- /R/RcppExports.R: -------------------------------------------------------------------------------- 1 | # Generated by using Rcpp::compileAttributes() -> do not edit by hand 2 | # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 3 | 4 | agg_sumCpp <- function(L, levels, category, plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) { 5 | .Call('_rasterly_agg_sumCpp', PACKAGE = 'rasterly', L, levels, category, plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) 6 | } 7 | 8 | agg_anyCpp <- function(L, levels, category, plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) { 9 | .Call('_rasterly_agg_anyCpp', PACKAGE = 'rasterly', L, levels, category, plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) 10 | } 11 | 12 | agg_meanCpp <- function(L, levels, category, plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) { 13 | .Call('_rasterly_agg_meanCpp', PACKAGE = 'rasterly', L, levels, category, plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) 14 | } 15 | 16 | agg_firstCpp <- function(L, levels, category, plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) { 17 | .Call('_rasterly_agg_firstCpp', PACKAGE = 'rasterly', L, levels, category, plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) 18 | } 19 | 20 | agg_lastCpp <- function(L, levels, category, plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) { 21 | .Call('_rasterly_agg_lastCpp', PACKAGE = 'rasterly', L, levels, category, plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) 22 | } 23 | 24 | agg_maxCpp <- function(L, levels, category, plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) { 25 | .Call('_rasterly_agg_maxCpp', PACKAGE = 'rasterly', L, levels, category, plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) 26 | } 27 | 28 | agg_minCpp <- function(L, levels, category, plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) { 29 | .Call('_rasterly_agg_minCpp', PACKAGE = 'rasterly', L, levels, category, plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) 30 | } 31 | 32 | aggregation_sumCpp <- function(plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) { 33 | .Call('_rasterly_aggregation_sumCpp', PACKAGE = 'rasterly', plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) 34 | } 35 | 36 | aggregation_anyCpp <- function(plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) { 37 | .Call('_rasterly_aggregation_anyCpp', PACKAGE = 'rasterly', plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) 38 | } 39 | 40 | aggregation_meanCpp <- function(plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) { 41 | .Call('_rasterly_aggregation_meanCpp', PACKAGE = 'rasterly', plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) 42 | } 43 | 44 | aggregation_firstCpp <- function(plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) { 45 | .Call('_rasterly_aggregation_firstCpp', PACKAGE = 'rasterly', plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) 46 | } 47 | 48 | aggregation_lastCpp <- function(plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) { 49 | .Call('_rasterly_aggregation_lastCpp', PACKAGE = 'rasterly', plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) 50 | } 51 | 52 | aggregation_maxCpp <- function(plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) { 53 | .Call('_rasterly_aggregation_maxCpp', PACKAGE = 'rasterly', plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) 54 | } 55 | 56 | aggregation_minCpp <- function(plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) { 57 | .Call('_rasterly_aggregation_minCpp', PACKAGE = 'rasterly', plot_width, plot_height, x_range, y_range, xlim, ylim, x, y, on, size, glyph) 58 | } 59 | 60 | -------------------------------------------------------------------------------- /man/add_rasterly.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/add_rasterly_heatmap.R, R/add_rasterly_image.R 3 | \name{add_rasterly} 4 | \alias{add_rasterly} 5 | \alias{add_rasterly_heatmap} 6 | \alias{add_rasterly_image} 7 | \title{Add "rasterly" trace to a Plotly visualization} 8 | \usage{ 9 | add_rasterly_heatmap( 10 | p, 11 | x = NULL, 12 | y = NULL, 13 | z = NULL, 14 | ..., 15 | data = NULL, 16 | inherit = TRUE, 17 | on = NULL, 18 | size = NULL, 19 | scaling = NULL 20 | ) 21 | 22 | add_rasterly_image( 23 | p, 24 | x = NULL, 25 | y = NULL, 26 | z = NULL, 27 | ..., 28 | data = NULL, 29 | inherit = TRUE, 30 | color = NULL, 31 | on = NULL, 32 | size = NULL 33 | ) 34 | } 35 | \arguments{ 36 | \item{p}{A \code{plotly} object} 37 | 38 | \item{x}{Numeric vector or expression. The x variable, to be passed on to \code{aes()}.} 39 | 40 | \item{y}{Numeric or expression. The y variable, to be passed on to \code{aes()}.} 41 | 42 | \item{z}{Numeric. A numeric matrix (optional), to be processed with \code{add_heatmap}.} 43 | 44 | \item{...}{Arguments (i.e., attributes) passed along to the trace type or \code{rasterly}.} 45 | 46 | \item{data}{A data.frame or \link[crosstalk]{SharedData} object (optional).} 47 | 48 | \item{inherit}{Logical. Inherit attributes from \link[plotly]{plotly}?} 49 | 50 | \item{on}{Numeric vector or expression. Provides the data on which to reduce, to be passed on to \code{aes()}.} 51 | 52 | \item{size}{Numeric vector or expression. Pixel size for each observation, to be passed on to \code{aes()}.} 53 | 54 | \item{scaling}{Character string or function. The scaling method to be used for the trace.} 55 | 56 | \item{color}{Numeric vector or expression. Pixel color for each observation, to be passed on to \code{aes()}.} 57 | } 58 | \description{ 59 | Add trace to a Plotly visualization. 60 | } 61 | \examples{ 62 | \dontrun{ 63 | if(requireNamespace("plotly") && requireNamespace("data.table") && 64 | requireNamespace("lubridate")) { 65 | # Load data 66 | url1 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data1.csv" 67 | ridesRaw_1 <- url1 \%>\% 68 | data.table::fread(stringsAsFactors = FALSE) 69 | url2 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data2.csv" 70 | ridesRaw_2 <- url2 \%>\% 71 | data.table::fread(stringsAsFactors = FALSE) 72 | url3 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data3.csv" 73 | ridesRaw_3 <- url3 \%>\% 74 | data.table::fread(stringsAsFactors = FALSE) 75 | ridesDf <- list(ridesRaw_1, ridesRaw_2, ridesRaw_3) \%>\% 76 | data.table::rbindlist() 77 | time <- lubridate::ymd_hms(ridesDf$`Date/Time`) 78 | ridesDf <- ridesDf[, 'Date/Time':=NULL][, list(Lat, 79 | Lon, 80 | hour = lubridate::hour(time), 81 | month = lubridate::month(time), 82 | day = lubridate::day(time))] 83 | ############################# add_rasterly_heatmap ############################# 84 | #### quick start 85 | p <- plot_ly(data = ridesDf) \%>\% 86 | add_rasterly_heatmap(x = ~Lat, y = ~Lon) 87 | p 88 | #### set artificial scaling function 89 | zeroOneTransform <- function(z) { 90 | minz <- min(z) 91 | maxz <- max(z) 92 | M <- matrix((z - minz)/(maxz - minz), nrow = dim(z)[1]) 93 | return(M) 94 | } 95 | plot_ly(data = ridesDf) \%>\% 96 | add_rasterly_heatmap(x = ~Lat, 97 | y = ~Lon, 98 | on = ~-Lat, 99 | reduction_func = "max", 100 | scaling = zeroOneTransform) \%>\% 101 | plotly::layout( 102 | xaxis = list( 103 | title = "x" 104 | ), 105 | yaxis = list( 106 | title = "y" 107 | ) 108 | ) 109 | ############################# add_rasterly_image ############################# 110 | p <- plot_ly(data = ridesDf) \%>\% 111 | add_rasterly_image(x = ~Lat, y = ~Lon, color = ~hour, 112 | # even `color_map` is deprecated, 113 | # it is still a good way to specify the color mapping 114 | color_map = hourColors_map, 115 | plot_width = 400, plot_height = 400) 116 | p 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /R/get_aesthetics.R: -------------------------------------------------------------------------------- 1 | get_aesthetics <- function(data = NULL, mapping = aes(), variable_check = FALSE, ...) { 2 | 3 | if(is.null(data)) stop("The 'data' aesthetic cannot be NULL; please supply a valid dataset.") 4 | if(!is.data.frame(data)) stop(paste(deparse(substitute(data)), "is not a data frame."), call. = FALSE) 5 | if(!data.table::is.data.table(data)) data <- data.table::as.data.table(data) 6 | 7 | if(rlang::is_empty(mapping)) stop("No aesthetics were supplied; please provide aesthetics for the data to rasterize.") 8 | 9 | mapping_names <- names(mapping) 10 | 11 | if(!"x" %in% mapping_names) 12 | stop("x is missing", call. = FALSE) 13 | 14 | if(!"y" %in% mapping_names) 15 | stop("y is missing", call. = FALSE) 16 | 17 | if("column" %in% mapping_names) { 18 | warning("`column` is deprecated, please use `on` instead.") 19 | mapping_names[which(mapping_names == "column")] <- "on" 20 | } 21 | 22 | if(!all(mapping_names %in% rasterly_aesthetics)) { 23 | message("Only `x`, `y`, `on` `size` and `color` parameters are currently accepted.") 24 | message("Additional aesthetics will be supported in the next release.") 25 | } 26 | 27 | column_names <- colnames(data) 28 | variable_names <- sapply(mapping, function(var) sub("~", "", rlang::expr_text(var))) 29 | 30 | if(all(variable_names %in% column_names) && all(!duplicated(variable_names))) { 31 | 32 | matchNameId <- function(nameA, nameB) {sapply(nameB, function (x) which(nameA == x))} 33 | 34 | column_names[matchNameId(column_names, variable_names)] <- mapping_names 35 | colnames(data) <- column_names 36 | 37 | # removing unused variables can reduce memory usage, but can slow execution time 38 | if(length(variable_names) != length(column_names) && variable_check) data <- data[, ..mapping_names] 39 | 40 | } else { 41 | 42 | for(i in seq_along(mapping)) { 43 | 44 | var <- mapping[[i]] 45 | name <- sub("~", "", rlang::expr_text(var)) 46 | 47 | # fastern code 48 | value <- data[[name]] 49 | if(is.null(value)) value <- rlang::eval_tidy(rlang::quo(!!var), data) 50 | 51 | data[[mapping_names[i]]] <- value 52 | } 53 | 54 | if(variable_check) data <- data[, ..mapping_names] 55 | } 56 | 57 | args <- list(...) 58 | abs_size <- args$size 59 | max_size <- args$max_size %||% 2 60 | 61 | if(!is.null(data$size) || !is.null(abs_size)) { 62 | 63 | if(is.null(abs_size)) { 64 | # standardized size 65 | std_size <- function(size, max_size) { 66 | maxS <- max(size) 67 | minS <- min(size) 68 | if(maxS == minS) { 69 | if(maxS < 1) stop("Pixel size cannot be less than one.") 70 | floor(size) 71 | } else { 72 | floor((size - minS)/(maxS - minS) * (max_size - 1)) 73 | } 74 | } 75 | data[, size := std_size(data$size, max_size)] 76 | } else { 77 | data[, size := abs_size] 78 | } 79 | } 80 | return(data) 81 | } 82 | 83 | rasterly_aesthetics <- c("x", "y", "on", "color", "size") 84 | 85 | # TODO: argument check, but it is so expensive! 86 | # switch(mapping_names[i], 87 | # "x" = { 88 | # if(!is.numeric(value)) 89 | # stop(paste("x variable:", paste0("`",name, "`"), "is not a numerical column"), 90 | # call. = FALSE) 91 | # if(is.infinite(value) || is.nan(value)) 92 | # stop(paste("x variable:", paste0("`",name, "`"), "has `NaN` value or `infinite` value"), 93 | # call. = FALSE) 94 | # }, 95 | # "y" = { 96 | # if(!is.numeric(value)) 97 | # stop(paste("y variable:", paste0("`",name, "`"), 'is not a numerical column'), 98 | # call. = FALSE) 99 | # if(is.infinite(value) || is.nan(value)) 100 | # stop(paste("y variable:", paste0("`",name, "`"), "has `NaN` value or `infinite` value"), 101 | # call. = FALSE) 102 | # }, 103 | # "on" = { 104 | # if(!is.numeric(value)) { 105 | # warning(paste("on variable:", paste0("`",name, "`"), "is not a numerical column"), 106 | # call. = FALSE) 107 | # value <- as.numeric(as.factor(value)) 108 | # } 109 | # }, 110 | # "color" = { 111 | # if(is.character(value)) { 112 | # value <- as.factor(value) 113 | # } 114 | # }) 115 | -------------------------------------------------------------------------------- /man/rasterly.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rasterly.R 3 | \name{rasterly} 4 | \alias{rasterly} 5 | \title{Easily and rapidly generate raster image data with support for Plotly.js} 6 | \usage{ 7 | rasterly( 8 | data = NULL, 9 | mapping = aes(), 10 | ..., 11 | plot_width = 600, 12 | plot_height = 600, 13 | x_range = NULL, 14 | y_range = NULL, 15 | background = "white", 16 | color = NULL, 17 | show_raster = TRUE, 18 | drop_data = FALSE, 19 | variable_check = FALSE 20 | ) 21 | } 22 | \arguments{ 23 | \item{data}{Dataset to use for generating the plot. If not provided, data must be supplied in each layer of the plot. 24 | For best performance, particularly when processing large datasets, use of \link[data.table]{data.table} is recommended.} 25 | 26 | \item{mapping}{Default list of aesthetic mappings to use for plot. The same with \code{ggplot2} \link[ggplot2]{aes}. 27 | See details.} 28 | 29 | \item{...}{Other arguments which will be passed through to layers.} 30 | 31 | \item{plot_width}{Integer. The width of the image to plot; must be a positive integer. A higher value indicates a higher resolution.} 32 | 33 | \item{plot_height}{Integer. The height of the image to plot; must be a positive integer. A higher value indicates a higher resolution.} 34 | 35 | \item{x_range}{Vector of type numeric. The range of \code{x}; it can be used to clip the image. For larger datasets, providing \code{x_range} 36 | may result in improved performance.} 37 | 38 | \item{y_range}{Vector of type numeric. The range of \code{y}; it can be used to clip the image. For larger datasets, providing \code{y_range} 39 | may result in improved performance.} 40 | 41 | \item{background}{Character. The background color of the image to plot.} 42 | 43 | \item{color}{Vector of type character. It will determine this color vector is a \code{color_map} or \code{color_key} automatically. 44 | \itemize{ 45 | \item{}{color_map: It has Color(s) used to draw each pixel. The \code{color_map} is extended by linear interpolation 46 | independently for RGB. The darkness of the mapped color depends upon the values of the aggregation matrix. 47 | } 48 | \item{}{color_key: Vector of type character. The \code{color_key} is used for categorical variables; 49 | it is passed when the \code{color} aesthetic is provided. 50 | } 51 | }} 52 | 53 | \item{show_raster}{Logical. Should the raster be displayed?} 54 | 55 | \item{drop_data}{Logical. When working with large datasets, drops the original data once processed according to the provided 56 | \code{aes()} parameters, using the \code{remove()} function. See details for additional information.} 57 | 58 | \item{variable_check}{Logical. If \code{TRUE}, drops unused columns to save memory; may result in reduced performance.} 59 | } 60 | \value{ 61 | An environment wrapped by a list which defines the properties of the raster data to be generated. 62 | } 63 | \description{ 64 | Create a rasterly object, to which aggregation layers may be added. This function is the first step in the process 65 | to generate raster image data using the \code{rasterly} package. 66 | } 67 | \details{ 68 | \itemize{ 69 | \item{}{The rasterly package currently supports five aesthetics via \code{aes()}: \code{x}, \code{y}, \code{on}, \code{color}, and \code{size}. 70 | The "on" aesthetic specifies the variable upon which the reduction function should be applied to generate the raster data. 71 | } 72 | \item{}{\code{drop_data} can help save space, particularly when large datasets are used. However, dropping the original dataset 73 | may result in errors when attempting to set or update \code{aes()} parameters within rasterly layers. 74 | } 75 | } 76 | } 77 | \note{ 78 | Calling \code{rasterly()} without providing \code{rasterly_...()} layers has no effect. 79 | More info can be found in \href{https://github.com/plotly/rasterly/blob/master/README.md}{README.md} 80 | } 81 | \examples{ 82 | \dontrun{ 83 | if(requireNamespace("data.table")) { 84 | url1 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data1.csv" 85 | ridesRaw_1 <- url1 \%>\% 86 | data.table::fread(stringsAsFactors = FALSE) 87 | url2 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data2.csv" 88 | ridesRaw_2 <- url2 \%>\% 89 | data.table::fread(stringsAsFactors = FALSE) 90 | url3 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data3.csv" 91 | ridesRaw_3 <- url3 \%>\% 92 | data.table::fread(stringsAsFactors = FALSE) 93 | ridesDf <- list(ridesRaw_1, ridesRaw_2, ridesRaw_3) \%>\% 94 | data.table::rbindlist() 95 | 96 | ridesDf \%>\% 97 | rasterly(mapping = aes(x = Lat, y = Lon)) \%>\% 98 | rasterly_points() 99 | }} 100 | 101 | } 102 | \seealso{ 103 | \link{rasterly_points}, \link{rasterly_build}, \link{[.rasterly}, \link{[<-.rasterly} 104 | \link{ggRasterly}, \link{plotRasterly} 105 | } 106 | -------------------------------------------------------------------------------- /R/rplot.R: -------------------------------------------------------------------------------- 1 | #' @title Rasterly plot 2 | #' @name rplot 3 | #' @description \code{rplot} is created to generate \code{rasterly} plot quickly but with base 4 | #' \link{plot} design. It is convenient but lacks flexibility and \link{rasterly} is highly 5 | #' recommended for a more versatile method. 6 | #' @param x,y Coordinates x, y for the plot. 7 | #' @param ... Other \code{rasterly} arguments to pass through. 8 | #' @export 9 | #' @seealso \link{rasterly} \link{rasterly_points} 10 | rplot <- function(x, y = NULL, ...) { 11 | UseMethod("rplot") 12 | } 13 | 14 | #' @rdname rplot 15 | #' @param plot_width Integer. The width of the image to plot; must be a positive integer. A higher value indicates a higher resolution. 16 | #' @param plot_height Integer. The height of the image to plot; must be a positive integer. A higher value indicates a higher resolution. 17 | #' @param x_range Vector of type numeric. The range of \code{x}; it can be used to clip the image. For larger datasets, providing \code{x_range} 18 | #' may result in improved performance. 19 | #' @param y_range Vector of type numeric. The range of \code{y}; it can be used to clip the image. For larger datasets, providing \code{y_range} 20 | #' may result in improved performance. 21 | #' @param background Character. The background color of the image to plot. 22 | #' @param reduction_func Function. A reduction function is used to aggregate data points into their pixel representations. Currently 23 | #' supported reduction operators are \code{sum}, \code{any}, \code{mean}, \code{m2}, \code{first}, \code{last}, \code{min} and \code{max}. Default is \code{sum}. See details. 24 | #' @param layout Character. The method used to generate layouts for multiple images. The default is \code{weighted}. Useful for categorical 25 | #' data (i.e. "color" is provided via \code{aes()}). \code{weighted} specifies that the final raster should be a weighted combination of each 26 | #' (categorical) aggregation matrix. Conversely, \code{cover} indicates that the afterwards objects will be drawn on top of 27 | #' the previous ones. 28 | #' @param glyph Character. Currently, only "circle" and "square" are supported; as the \code{size} of the pixels increases, how should they 29 | #' spread out -- should the pattern be circular or square? Other glyphs may be added in the future. 30 | #' @details \code{rasterly} arguments are passed through via \code{...}. But some of them are noticeable. 31 | #' \itemize{ 32 | #' \item{\code{size}: Size can be either a specified size (1, 2, 3, etc) or a mapping variable. Since \code{rasterly} does not provide 33 | #' point to point display, if the length of input \code{size} is the same with the length of \code{x} (or \code{y}). It will be treated as 34 | #' a mapping variable.} 35 | #' \item{\code{color}: Color can be either a color map vector or a mapping variable. If the length of \code{color} is equal to the length of 36 | #' \code{x} (or \code{y}). It will be treated as a mapping variable.} 37 | #' \item{\code{on}: On is always treated as a mapping variable.} 38 | #' } 39 | #' @export 40 | #' @examples 41 | #' if(requireNamespace("ggplot2")) { 42 | #' library(ggplot2) 43 | #' # `color` represents a variable here 44 | #' with(diamonds, 45 | #' rplot(x = carat, y = price, color = color) 46 | #' ) 47 | #' # `color` represents an actual color vector 48 | #' with(diamonds, 49 | #' rplot(x = carat, y = price, color = fire_map) 50 | #' ) 51 | #' } 52 | rplot.default <- function(x, y = NULL, ..., 53 | plot_width = 600, plot_height = 600, 54 | x_range = NULL, y_range = NULL, 55 | background = "white", 56 | reduction_func = NULL, 57 | layout = NULL, 58 | glyph = NULL) { 59 | 60 | xy <- grDevices::xy.coords(x, y) 61 | data <- data.table::data.table(x = xy$x, y = xy$y) 62 | mapping <- aes(x = x, y = y) 63 | n <- dim(data)[1] 64 | 65 | args <- list(...) 66 | 67 | for(aes_name in setdiff(rasterly_aesthetics, c("x", "y"))) { 68 | var <- args[[aes_name]] 69 | 70 | if(length(var) == n) { 71 | data <- data[, rlang::expr_name(aes_name) := var] 72 | aes_names <- names(mapping) 73 | mapping <- mbind(rlang::quo(!!rlang::sym(aes_name)), mapping) %>% 74 | stats::setNames(., c(aes_name, aes_names)) 75 | args[[aes_name]] <- NULL 76 | } 77 | } 78 | 79 | r <- do.call( 80 | rasterly, 81 | c( 82 | list( 83 | data = data, 84 | mapping = mapping, 85 | plot_width = plot_width, 86 | plot_height = plot_height, 87 | background = background, 88 | x_range = x_range, 89 | y_range = y_range 90 | ), 91 | args 92 | ) 93 | ) %>% 94 | rasterly_points(reduction_func = reduction_func, 95 | layout = layout, 96 | glyph = glyph) %>% 97 | rasterly_build() 98 | 99 | print(r) 100 | } 101 | -------------------------------------------------------------------------------- /man/ggRasterly.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ggRasterly.R 3 | \name{ggRasterly} 4 | \alias{ggRasterly} 5 | \title{ggRasterly} 6 | \usage{ 7 | ggRasterly( 8 | data = NULL, 9 | mapping = aes(), 10 | ..., 11 | plot_width = 600, 12 | plot_height = 600, 13 | x_range = NULL, 14 | y_range = NULL, 15 | background = "white", 16 | color = NULL, 17 | show_raster = TRUE, 18 | drop_data = FALSE, 19 | variable_check = FALSE, 20 | alpha = 0.5, 21 | shape = 15, 22 | point_size = 0.5 23 | ) 24 | } 25 | \arguments{ 26 | \item{data}{Dataset to use for generating the plot. If not provided, data must be supplied in each layer of the plot. 27 | For best performance, particularly when processing large datasets, use of \link[data.table]{data.table} is recommended.} 28 | 29 | \item{mapping}{Default list of aesthetic mappings to use for plot. The same with \code{ggplot2} \link[ggplot2]{aes}. 30 | See details.} 31 | 32 | \item{...}{Other arguments which will be passed through to layers.} 33 | 34 | \item{plot_width}{Integer. The width of the image to plot; must be a positive integer. A higher value indicates a higher resolution.} 35 | 36 | \item{plot_height}{Integer. The height of the image to plot; must be a positive integer. A higher value indicates a higher resolution.} 37 | 38 | \item{x_range}{Vector of type numeric. The range of \code{x}; it can be used to clip the image. For larger datasets, providing \code{x_range} 39 | may result in improved performance.} 40 | 41 | \item{y_range}{Vector of type numeric. The range of \code{y}; it can be used to clip the image. For larger datasets, providing \code{y_range} 42 | may result in improved performance.} 43 | 44 | \item{background}{Character. The background color of the image to plot.} 45 | 46 | \item{color}{Vector of type character. It will determine this color vector is a \code{color_map} or \code{color_key} automatically. 47 | \itemize{ 48 | \item{}{color_map: It has Color(s) used to draw each pixel. The \code{color_map} is extended by linear interpolation 49 | independently for RGB. The darkness of the mapped color depends upon the values of the aggregation matrix. 50 | } 51 | \item{}{color_key: Vector of type character. The \code{color_key} is used for categorical variables; 52 | it is passed when the \code{color} aesthetic is provided. 53 | } 54 | }} 55 | 56 | \item{show_raster}{Logical. Should the raster be displayed?} 57 | 58 | \item{drop_data}{Logical. When working with large datasets, drops the original data once processed according to the provided 59 | \code{aes()} parameters, using the \code{remove()} function. See details for additional information.} 60 | 61 | \item{variable_check}{Logical. If \code{TRUE}, drops unused columns to save memory; may result in reduced performance.} 62 | 63 | \item{alpha}{The transparency of points, from 0 to 1.} 64 | 65 | \item{shape}{The shape of points, see \link{pch}.} 66 | 67 | \item{point_size}{The size of points.} 68 | } 69 | \value{ 70 | a `ggplot` object 71 | } 72 | \description{ 73 | Display large data set in \code{ggplot}. 74 | } 75 | \examples{ 76 | \dontrun{ 77 | if(requireNamespace("ggplot2") && requireNamespace("data.table") && 78 | requireNamespace("lubridate")) { 79 | # Load data 80 | url1 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data1.csv" 81 | ridesRaw_1 <- url1 \%>\% 82 | data.table::fread(stringsAsFactors = FALSE) 83 | url2 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data2.csv" 84 | ridesRaw_2 <- url2 \%>\% 85 | data.table::fread(stringsAsFactors = FALSE) 86 | url3 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data3.csv" 87 | ridesRaw_3 <- url3 \%>\% 88 | data.table::fread(stringsAsFactors = FALSE) 89 | 90 | ridesDf <- list(ridesRaw_1, ridesRaw_2, ridesRaw_3) \%>\% 91 | data.table::rbindlist() 92 | 93 | time <- lubridate::ymd_hms(ridesDf$`Date/Time`) 94 | ridesDf <- ridesDf[, 'Date/Time':=NULL][, list(Lat, 95 | Lon, 96 | hour = lubridate::hour(time), 97 | month = lubridate::month(time), 98 | day = lubridate::day(time))] 99 | 100 | # continuous variable legend 101 | ggRasterly(data = ridesDf, 102 | mapping = aes(x = Lat, y = Lon), 103 | color = fire_map 104 | ) 105 | # discreate variable legend 106 | ggRasterly(data = ridesDf, 107 | mapping = aes(x = Lat, y = Lon, color = hour), 108 | color = hourColors_map 109 | ) + 110 | ggplot2::labs(title = "New York Uber", 111 | subtitle = "Apr to Sept, 2014", 112 | caption = 113 | "https://raw.githubusercontent.com/plotly/datasets/master") 114 | } 115 | } 116 | } 117 | \seealso{ 118 | \code{\link{plotRasterly}}, \code{\link{plot.rasterly}} 119 | } 120 | -------------------------------------------------------------------------------- /man/plotRasterly.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plotRasterly.R 3 | \name{plotRasterly} 4 | \alias{plotRasterly} 5 | \title{plotRasterly} 6 | \usage{ 7 | plotRasterly( 8 | data = NULL, 9 | mapping = aes(), 10 | ..., 11 | plot_width = 400, 12 | plot_height = 400, 13 | x_range = NULL, 14 | y_range = NULL, 15 | background = "white", 16 | color = NULL, 17 | show_raster = TRUE, 18 | drop_data = FALSE, 19 | variable_check = FALSE, 20 | alpha = 0.5, 21 | shape = 19, 22 | point_size = 0.5, 23 | as_image = FALSE, 24 | sizing = c("stretch", "fill", "contain") 25 | ) 26 | } 27 | \arguments{ 28 | \item{data}{Dataset to use for generating the plot. If not provided, data must be supplied in each layer of the plot. 29 | For best performance, particularly when processing large datasets, use of \link[data.table]{data.table} is recommended.} 30 | 31 | \item{mapping}{Default list of aesthetic mappings to use for plot. The same with \code{ggplot2} \link[ggplot2]{aes}. 32 | See details.} 33 | 34 | \item{...}{Other arguments which will be passed through to layers.} 35 | 36 | \item{plot_width}{Integer. The width of the image to plot; must be a positive integer. A higher value indicates a higher resolution.} 37 | 38 | \item{plot_height}{Integer. The height of the image to plot; must be a positive integer. A higher value indicates a higher resolution.} 39 | 40 | \item{x_range}{Vector of type numeric. The range of \code{x}; it can be used to clip the image. For larger datasets, providing \code{x_range} 41 | may result in improved performance.} 42 | 43 | \item{y_range}{Vector of type numeric. The range of \code{y}; it can be used to clip the image. For larger datasets, providing \code{y_range} 44 | may result in improved performance.} 45 | 46 | \item{background}{Character. The background color of the image to plot.} 47 | 48 | \item{color}{Vector of type character. It will determine this color vector is a \code{color_map} or \code{color_key} automatically. 49 | \itemize{ 50 | \item{}{color_map: It has Color(s) used to draw each pixel. The \code{color_map} is extended by linear interpolation 51 | independently for RGB. The darkness of the mapped color depends upon the values of the aggregation matrix. 52 | } 53 | \item{}{color_key: Vector of type character. The \code{color_key} is used for categorical variables; 54 | it is passed when the \code{color} aesthetic is provided. 55 | } 56 | }} 57 | 58 | \item{show_raster}{Logical. Should the raster be displayed?} 59 | 60 | \item{drop_data}{Logical. When working with large datasets, drops the original data once processed according to the provided 61 | \code{aes()} parameters, using the \code{remove()} function. See details for additional information.} 62 | 63 | \item{variable_check}{Logical. If \code{TRUE}, drops unused columns to save memory; may result in reduced performance.} 64 | 65 | \item{alpha}{The transparency of points, from 0 to 1.} 66 | 67 | \item{shape}{The shape of points, see \link{pch}.} 68 | 69 | \item{point_size}{The size of points.} 70 | 71 | \item{as_image}{Logical value. If \code{FALSE}, image raster will be transformed into a data frame, hence a points layer 72 | would be pipped on \code{plotly}; conversely, a raster layer will be added.} 73 | 74 | \item{sizing}{It affects only with \code{as_image = TRUE}. Specifies which dimension of the image to constrain. 75 | One of "stretch" "fill", "contain". see https://plot.ly/r/reference/#Layout_and_layout_style_objects} 76 | } 77 | \value{ 78 | a \code{plotly} widget 79 | } 80 | \description{ 81 | Display large data set in \code{plotly} 82 | } 83 | \examples{ 84 | \dontrun{ 85 | library(rasterly) 86 | if(requireNamespace("plotly") && 87 | requireNamespace("data.table") && 88 | requireNamespace("lubridate")) { 89 | # Load data 90 | url1 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data1.csv" 91 | ridesRaw_1 <- url1 \%>\% 92 | data.table::fread(stringsAsFactors = FALSE) 93 | url2 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data2.csv" 94 | ridesRaw_2 <- url2 \%>\% 95 | data.table::fread(stringsAsFactors = FALSE) 96 | url3 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data3.csv" 97 | ridesRaw_3 <- url3 \%>\% 98 | data.table::fread(stringsAsFactors = FALSE) 99 | ridesDf <- list(ridesRaw_1, ridesRaw_2, ridesRaw_3) \%>\% 100 | data.table::rbindlist() 101 | 102 | time <- lubridate::ymd_hms(ridesDf$`Date/Time`) 103 | ridesDf <- 104 | ridesDf[, 'Date/Time':=NULL][, list(Lat, 105 | Lon, 106 | hour = lubridate::hour(time), 107 | month = lubridate::month(time), 108 | day = lubridate::day(time))] 109 | # A point layer is added 110 | plotRasterly(data = ridesDf, 111 | mapping = aes(x = Lat, y = Lon, color = hour), 112 | color = hourColors_map, 113 | as_image = FALSE) 114 | # An image layer is added 115 | plotRasterly(data = ridesDf, 116 | mapping = aes(x = Lat, y = Lon, color = hour), 117 | color = hourColors_map, 118 | as_image = TRUE) 119 | 120 | } 121 | } 122 | } 123 | \seealso{ 124 | \code{\link{ggRasterly}}, \code{\link{plot.rasterly}} 125 | } 126 | -------------------------------------------------------------------------------- /R/get_arguments.R: -------------------------------------------------------------------------------- 1 | get_range <- function(x_range, y_range, x, y) { 2 | 3 | x_range <- x_range %||% c(min(x), max(x)) 4 | if(length(x_range) != 2 || !is.numeric(x_range)) stop("x_range should be a vector of type numeric with a length of 2.") 5 | if(x_range[1] > x_range[2]) x_range <- sort(x_range) 6 | 7 | 8 | y_range <- y_range %||% c(min(y), max(y)) 9 | if(length(y_range) != 2 || !is.numeric(y_range)) stop("y_range should be a vector of type numeric with a length of 2.") 10 | if(y_range[1] > y_range[2]) y_range <- sort(y_range) 11 | 12 | return( 13 | list( 14 | x_range = x_range, 15 | y_range = y_range 16 | ) 17 | ) 18 | } 19 | 20 | get_background <- function(envir, ...) { 21 | 22 | args <- list(...) 23 | 24 | background <- args$background %||% .get("background", envir = envir) %||% "white" 25 | 26 | return(background) 27 | } 28 | 29 | get_color <- function(envir, mapping, ...) { 30 | 31 | args <- list(...) 32 | is_color_in_mapping <- mapping$color 33 | if(is.null(is_color_in_mapping)) { 34 | # color_map 35 | color <- args$color_map %||% args$color 36 | } else { 37 | # color_key 38 | color <- args$color_key %||% args$color 39 | } 40 | color_warning(envir, args) 41 | 42 | return(color %||% .get("color", envir = envir)) 43 | } 44 | 45 | get_mapped_color <- function(color = c('lightblue','darkblue'), 46 | span = 50) { 47 | 48 | # get color rgb value 49 | rgb_num <- get_rgb_num(color) 50 | span <- max(span, length(color)) 51 | # use interpolation to extend color 52 | col_index <- interpolation(red = rgb_num$red, green = rgb_num$green, blue = rgb_num$blue, 53 | span = span) 54 | 55 | col_index 56 | } 57 | 58 | get_alpha <- function(envir, ...) { 59 | 60 | args <- list(...) 61 | 62 | alpha <- args$alpha %||% .get("alpha", envir = envir) %||% 1 63 | 64 | stopifnot( 65 | exprs = { 66 | is.numeric(alpha) 67 | alpha <= 1 && alpha >= 0 68 | } 69 | ) 70 | 71 | return(alpha) 72 | } 73 | 74 | get_span <- function(envir, ...) { 75 | 76 | args <- list(...) 77 | 78 | span <- args$span %||% .get("span", envir = envir) %||% 50 79 | 80 | stopifnot( 81 | exprs = { 82 | is.numeric(span) 83 | } 84 | ) 85 | 86 | return(span) 87 | } 88 | 89 | get_max_size <- function(envir, max_size) { 90 | 91 | max_size <- max_size %||% .get("max_size", envir = envir) %||% 2 92 | 93 | if(!is.numeric(max_size)) stop("`max_size` is a numerical value", call. = FALSE) 94 | if(length(max_size) > 1) warning("More than one `max_size` was passed, but only the first element will be used.", 95 | call. = FALSE) 96 | max_size <- ceiling(max_size)[1] 97 | if(max_size < 2) { 98 | warning("`max_size` cannot be smaller than 2", call. = FALSE) 99 | max_size <- 2 100 | } 101 | 102 | return(max_size) 103 | } 104 | 105 | get_size <- function(envir, ...) { 106 | 107 | args <- list(...) 108 | 109 | size <- args$size %||% .get("size", envir = envir) %||% 1 110 | 111 | if(!is.numeric(size)) stop("`size` must be an integer.", call. = FALSE) 112 | if(length(size) > 1) { 113 | warning("More than one `size` was passed, but only the first element will be used.", call. = FALSE) 114 | size <- size[1] 115 | } 116 | if(size < 1) { 117 | warning("`size` should be larger than or equal to 1.", call. = FALSE) 118 | size <- 1 119 | } 120 | 121 | return(size) 122 | } 123 | 124 | get_variable_check <- function(envir, ...) { 125 | 126 | args <- list(...) 127 | 128 | variable_check <- args$variable_check %||% .get("variable_check", envir = envir) 129 | 130 | if(!is.logical(variable_check) || is.null(variable_check) || is.na(variable_check)) { 131 | warning("variable_check must be a logical value; assuming FALSE.") 132 | variable_check <- FALSE 133 | } 134 | 135 | return(variable_check) 136 | } 137 | 138 | get_layout <- function(envir, ...) { 139 | 140 | args <- list(...) 141 | parent_args <- .get("args", envir = envir) 142 | 143 | layout <- args$layout %||% parent_args$layout %||% "weighted" 144 | 145 | if(!layout %in% c("weighted", "cover")) { 146 | warning("`layout` options in this release include 'weighted' or 'cover'; assuming 'weighted'", call. = FALSE) 147 | layout <- "weighted" 148 | } 149 | 150 | return(layout) 151 | } 152 | 153 | get_glyph <- function(envir, glyph) { 154 | 155 | parent_args <- .get("args", envir = envir) 156 | glyph <- glyph %||% parent_args$glyph %||% "circle" 157 | 158 | if(!glyph %in% c("circle", "square")) { 159 | warning("`glyph` options in this release include 'circle' or 'square'; assuming 'circle'", call. = FALSE) 160 | glyph <- "circle" 161 | } 162 | 163 | return(glyph) 164 | } 165 | 166 | get_x_pretty <- function(envir, x_pretty) { 167 | 168 | parent_args <- .get("args", envir = envir) 169 | return(x_pretty %||% parent_args$x_pretty) 170 | } 171 | 172 | get_y_pretty <- function(envir, y_pretty) { 173 | 174 | parent_args <- .get("args", envir = envir) 175 | return(y_pretty %||% parent_args$y_pretty) 176 | } 177 | 178 | get_group_by_data_table <- function(envir, group_by_data_table) { 179 | 180 | parent_args <- .get("args", envir = envir) 181 | group_by_data_table <- group_by_data_table %||% parent_args$group_by_data_table %||% TRUE 182 | 183 | if(!is.logical(group_by_data_table)) { 184 | warning("group_by_data_table must be a logical value; assuming TRUE.") 185 | group_by_data_table <- TRUE 186 | } 187 | 188 | return(group_by_data_table) 189 | } 190 | -------------------------------------------------------------------------------- /R/as_raster.R: -------------------------------------------------------------------------------- 1 | as_raster <- function(x, ...) { 2 | UseMethod("as_raster", x) 3 | } 4 | 5 | as_raster.matrix <- function(x, color = c('lightblue','darkblue'), span = 50, 6 | zeroIgnored = TRUE, image = NULL, background = "#FFFFFF", 7 | alpha = 1, layout = c("weighted", "cover")) { 8 | 9 | layout <- match.arg(layout) 10 | span <- max(span, length(color)) 11 | # get dimension 12 | dimM <- dim(x) 13 | which_is_not_zero <- !isZero(x) 14 | 15 | if(sum(which_is_not_zero) > 0) { 16 | 17 | cdf <- get_cdf(M = x, zeroIgnored = TRUE, which_is_not_zero = which_is_not_zero) 18 | id <- floor(cdf(x) * (span - 1))[which_is_not_zero] + 1 19 | 20 | col_index <- get_mapped_color(color = color, 21 | span = span) 22 | 23 | red <- col_index$red[id] 24 | green <- col_index$green[id] 25 | blue <- col_index$blue[id] 26 | 27 | if(is.null(image)) { 28 | # build image 29 | image <- rep(background, dimM[1]*dimM[2]) 30 | } else { 31 | image <- image[dimM[1]:1, ] 32 | if(layout == "weighted") { 33 | colors <- get_rgb_num(image[which_is_not_zero]) 34 | red <- (red + colors$red)/2 35 | green <- (green + colors$green)/2 36 | blue <- (blue + colors$blue)/2 37 | } else if (layout == "cover") { 38 | NULL 39 | } else stop("Unknown `layout` method provided; `weighted` or `cover` are currently supported approaches.") 40 | } 41 | 42 | red <- red/255 43 | green <- green/255 44 | blue <- blue/255 45 | red[red < 0] <- 0 46 | green[green < 0] <- 0 47 | blue[blue < 0] <- 0 48 | red[red > 1] <- 1 49 | green[green > 1] <- 1 50 | blue[blue > 1] <- 1 51 | 52 | image[which_is_not_zero] <- grDevices::rgb(red = red, 53 | green = green, 54 | blue = blue, 55 | alpha = alpha, 56 | maxColorValue = 1) 57 | } else { 58 | # x is a zero matrix 59 | image <- rep(background, dimM[1] * dimM[2]) 60 | } 61 | 62 | image <- matrix(image, nrow = dimM[1]) 63 | image <- image[dimM[1]:1, ] 64 | return(image) 65 | } 66 | 67 | as_raster.list <- function(x, color = NULL, span = 50, 68 | zeroIgnored = TRUE, image = NULL, background = "#FFFFFF", 69 | alpha = 1, layout = c("weighted", "cover")) { 70 | 71 | n <- length(x) 72 | if(missing(color) || is.null(color)) color <- gg_color_hue(n) 73 | stopifnot( 74 | exprs = { 75 | length(color) >= n 76 | } 77 | ) 78 | 79 | layout <- match.arg(layout) 80 | dimM <- dim(x[[1]]) 81 | 82 | if(layout == "weighted") { 83 | 84 | color_key_rgb_num <- get_rgb_num(color) 85 | # weighted x 86 | summed_M <- Reduce('+', x) 87 | # used for divide 88 | summed_M[isZero(summed_M)] <- 1 89 | red <- green <- blue <- matrix() 90 | hide <- lapply(1:n, 91 | function(i){ 92 | M <- x[[i]] 93 | M <- M/summed_M 94 | 95 | if(i == 1) { 96 | red <<- color_key_rgb_num$red[i] * M 97 | green <<- color_key_rgb_num$green[i] * M 98 | blue <<- color_key_rgb_num$blue[i] * M 99 | } else { 100 | red <<- red + color_key_rgb_num$red[i] * M 101 | green <<- green + color_key_rgb_num$green[i] * M 102 | blue <<- blue + color_key_rgb_num$blue[i] * M 103 | } 104 | }) 105 | 106 | if(is.null(image)) { 107 | # build image 108 | image <- rep(background, dimM[1]*dimM[2]) 109 | } else { 110 | image <- image[dimM[1]:1, ] 111 | not_background <- image != background 112 | image_rgb_num <- get_rgb_num(image[not_background]) 113 | # In R, matrix + vector, vector will be converted to matrix first. 114 | red[not_background] <- image_rgb_num$red 115 | green[not_background] <- image_rgb_num$green 116 | blue[not_background] <- image_rgb_num$blue 117 | } 118 | 119 | red <- red/255 120 | green <- green/255 121 | blue <- blue/255 122 | red[red < 0] <- 0 123 | green[green < 0] <- 0 124 | blue[blue < 0] <- 0 125 | red[red > 1] <- 1 126 | green[green > 1] <- 1 127 | blue[blue > 1] <- 1 128 | 129 | colors <- grDevices::rgb(red = red, 130 | green = green, 131 | blue = blue, 132 | alpha = alpha, 133 | maxColorValue = 1) 134 | 135 | colors[grepl("#000000", colors)] <- background 136 | 137 | image <- matrix(colors, nrow = dimM[1]) 138 | image <- image[dimM[1]:1, ] 139 | } else if (layout == "cover") { 140 | 141 | if(is.null(image)) { 142 | image <- matrix(rep(background, dimM[1]*dimM[2]), nrow = dimM[1]) 143 | } 144 | 145 | lapply(1:n, 146 | function(i){ 147 | image <<- as_raster(x = x[[i]], 148 | color = c(background, color[i]), 149 | span = span, 150 | zeroIgnored = zeroIgnored, 151 | image = image, 152 | background = background, 153 | alpha = alpha, layout = layout) 154 | }) 155 | } else 156 | stop("Unknown `layout` method provided; `weighted` or `cover` are currently supported approaches.") 157 | 158 | return(image) 159 | } 160 | -------------------------------------------------------------------------------- /R/plotRasterly.R: -------------------------------------------------------------------------------- 1 | #' @title plotRasterly 2 | #' @description Display large data set in \code{plotly} 3 | #' @inheritParams ggRasterly 4 | #' @param as_image Logical value. If \code{FALSE}, image raster will be transformed into a data frame, hence a points layer 5 | #' would be pipped on \code{plotly}; conversely, a raster layer will be added. 6 | #' @param sizing It affects only with \code{as_image = TRUE}. Specifies which dimension of the image to constrain. 7 | #' One of "stretch" "fill", "contain". see https://plot.ly/r/reference/#Layout_and_layout_style_objects 8 | #' @return a \code{plotly} widget 9 | #' 10 | #' @seealso \code{\link{ggRasterly}}, \code{\link{plot.rasterly}} 11 | #' 12 | #' @export 13 | #' 14 | #' @examples 15 | #' \dontrun{ 16 | #' library(rasterly) 17 | #' if(requireNamespace("plotly") && 18 | #' requireNamespace("data.table") && 19 | #' requireNamespace("lubridate")) { 20 | #' # Load data 21 | #' url1 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data1.csv" 22 | #' ridesRaw_1 <- url1 %>% 23 | #' data.table::fread(stringsAsFactors = FALSE) 24 | #' url2 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data2.csv" 25 | #' ridesRaw_2 <- url2 %>% 26 | #' data.table::fread(stringsAsFactors = FALSE) 27 | #' url3 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data3.csv" 28 | #' ridesRaw_3 <- url3 %>% 29 | #' data.table::fread(stringsAsFactors = FALSE) 30 | #' ridesDf <- list(ridesRaw_1, ridesRaw_2, ridesRaw_3) %>% 31 | #' data.table::rbindlist() 32 | #' 33 | #' time <- lubridate::ymd_hms(ridesDf$`Date/Time`) 34 | #' ridesDf <- 35 | #' ridesDf[, 'Date/Time':=NULL][, list(Lat, 36 | #' Lon, 37 | #' hour = lubridate::hour(time), 38 | #' month = lubridate::month(time), 39 | #' day = lubridate::day(time))] 40 | #' # A point layer is added 41 | #' plotRasterly(data = ridesDf, 42 | #' mapping = aes(x = Lat, y = Lon, color = hour), 43 | #' color = hourColors_map, 44 | #' as_image = FALSE) 45 | #' # An image layer is added 46 | #' plotRasterly(data = ridesDf, 47 | #' mapping = aes(x = Lat, y = Lon, color = hour), 48 | #' color = hourColors_map, 49 | #' as_image = TRUE) 50 | #' 51 | #' } 52 | #' } 53 | plotRasterly <- function(data = NULL, 54 | mapping = aes(), 55 | ..., 56 | plot_width = 400, plot_height = 400, 57 | x_range = NULL, y_range = NULL, 58 | background = "white", 59 | color = NULL, 60 | show_raster = TRUE, 61 | drop_data = FALSE, 62 | variable_check = FALSE, 63 | alpha = 0.5, 64 | shape = 19, 65 | point_size = 0.5, 66 | as_image = FALSE, 67 | sizing = c("stretch", "fill", "contain")) { 68 | 69 | if(!show_raster) return(plotly::plot_ly()) 70 | 71 | if(as_image) { 72 | 73 | mapping <- rename_mapping(mapping) 74 | rastObj <- rasterly(data = data, 75 | mapping = mapping, 76 | ..., 77 | plot_width = plot_width, 78 | plot_height = plot_height, 79 | x_range = x_range, 80 | y_range = y_range, 81 | background = background, 82 | color = color, 83 | show_raster = show_raster, 84 | drop_data = drop_data, 85 | variable_check = variable_check) %>% 86 | rasterly_points() %>% 87 | rasterly_build() 88 | 89 | image <- rastObj$image 90 | if(is.null(image)) 91 | stop("No image is found. Consider set `show_raster = TRUE` in `rasterly()`?", call. = FALSE) 92 | 93 | var_names <- unlist(rastObj$variable_names) 94 | 95 | sizing <- match.arg(sizing) 96 | 97 | p <- plotly::plot_ly( 98 | width = rastObj$plot_width, 99 | height = rastObj$plot_height 100 | ) %>% 101 | plotly::layout( 102 | images = list( 103 | source = plotly::raster2uri(image), # converts a raster object to a data URI. 104 | xref = "x", 105 | yref = "y", 106 | x = rastObj$x_range[1], 107 | y = rastObj$y_range[1], 108 | sizex = diff(rastObj$x_range), 109 | sizey = diff(rastObj$y_range), 110 | xanchor = "left", 111 | yanchor = "bottom", 112 | sizing = sizing 113 | ), 114 | ..., 115 | xaxis = list( 116 | range = rastObj$x_range, 117 | title = get_varnames(var_names, "x") 118 | ), 119 | yaxis = list( 120 | range = rastObj$y_range, 121 | title = get_varnames(var_names, "y") 122 | ), 123 | plot_bgcolor = rastObj$background 124 | ) 125 | } else { 126 | p <- ggRasterly( 127 | data = data, 128 | mapping = mapping, 129 | ..., 130 | plot_width = plot_width, 131 | plot_height = plot_height, 132 | x_range = x_range, y_range = y_range, 133 | background = background, 134 | color = color, 135 | show_raster = show_raster, 136 | drop_data = drop_data, 137 | variable_check = variable_check, 138 | alpha = alpha, 139 | shape = shape, 140 | point_size = point_size 141 | ) %>% 142 | plotly::ggplotly() 143 | } 144 | return(p) 145 | } 146 | -------------------------------------------------------------------------------- /docs/pkgdown.css: -------------------------------------------------------------------------------- 1 | /* Sticky footer */ 2 | 3 | /** 4 | * Basic idea: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ 5 | * Details: https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css 6 | * 7 | * .Site -> body > .container 8 | * .Site-content -> body > .container .row 9 | * .footer -> footer 10 | * 11 | * Key idea seems to be to ensure that .container and __all its parents__ 12 | * have height set to 100% 13 | * 14 | */ 15 | 16 | html, body { 17 | height: 100%; 18 | } 19 | 20 | body > .container { 21 | display: flex; 22 | height: 100%; 23 | flex-direction: column; 24 | } 25 | 26 | body > .container .row { 27 | flex: 1 0 auto; 28 | } 29 | 30 | footer { 31 | margin-top: 45px; 32 | padding: 35px 0 36px; 33 | border-top: 1px solid #e5e5e5; 34 | color: #666; 35 | display: flex; 36 | flex-shrink: 0; 37 | } 38 | footer p { 39 | margin-bottom: 0; 40 | } 41 | footer div { 42 | flex: 1; 43 | } 44 | footer .pkgdown { 45 | text-align: right; 46 | } 47 | footer p { 48 | margin-bottom: 0; 49 | } 50 | 51 | img.icon { 52 | float: right; 53 | } 54 | 55 | img { 56 | max-width: 100%; 57 | } 58 | 59 | /* Fix bug in bootstrap (only seen in firefox) */ 60 | summary { 61 | display: list-item; 62 | } 63 | 64 | /* Typographic tweaking ---------------------------------*/ 65 | 66 | .contents .page-header { 67 | margin-top: calc(-60px + 1em); 68 | } 69 | 70 | /* Section anchors ---------------------------------*/ 71 | 72 | a.anchor { 73 | margin-left: -30px; 74 | display:inline-block; 75 | width: 30px; 76 | height: 30px; 77 | visibility: hidden; 78 | 79 | background-image: url(./link.svg); 80 | background-repeat: no-repeat; 81 | background-size: 20px 20px; 82 | background-position: center center; 83 | } 84 | 85 | .hasAnchor:hover a.anchor { 86 | visibility: visible; 87 | } 88 | 89 | @media (max-width: 767px) { 90 | .hasAnchor:hover a.anchor { 91 | visibility: hidden; 92 | } 93 | } 94 | 95 | 96 | /* Fixes for fixed navbar --------------------------*/ 97 | 98 | .contents h1, .contents h2, .contents h3, .contents h4 { 99 | padding-top: 60px; 100 | margin-top: -40px; 101 | } 102 | 103 | /* Sidebar --------------------------*/ 104 | 105 | #sidebar { 106 | margin-top: 30px; 107 | position: -webkit-sticky; 108 | position: sticky; 109 | top: 70px; 110 | } 111 | #sidebar h2 { 112 | font-size: 1.5em; 113 | margin-top: 1em; 114 | } 115 | 116 | #sidebar h2:first-child { 117 | margin-top: 0; 118 | } 119 | 120 | #sidebar .list-unstyled li { 121 | margin-bottom: 0.5em; 122 | } 123 | 124 | .orcid { 125 | height: 16px; 126 | /* margins are required by official ORCID trademark and display guidelines */ 127 | margin-left:4px; 128 | margin-right:4px; 129 | vertical-align: middle; 130 | } 131 | 132 | /* Reference index & topics ----------------------------------------------- */ 133 | 134 | .ref-index th {font-weight: normal;} 135 | 136 | .ref-index td {vertical-align: top;} 137 | .ref-index .icon {width: 40px;} 138 | .ref-index .alias {width: 40%;} 139 | .ref-index-icons .alias {width: calc(40% - 40px);} 140 | .ref-index .title {width: 60%;} 141 | 142 | .ref-arguments th {text-align: right; padding-right: 10px;} 143 | .ref-arguments th, .ref-arguments td {vertical-align: top;} 144 | .ref-arguments .name {width: 20%;} 145 | .ref-arguments .desc {width: 80%;} 146 | 147 | /* Nice scrolling for wide elements --------------------------------------- */ 148 | 149 | table { 150 | display: block; 151 | overflow: auto; 152 | } 153 | 154 | /* Syntax highlighting ---------------------------------------------------- */ 155 | 156 | pre { 157 | word-wrap: normal; 158 | word-break: normal; 159 | border: 1px solid #eee; 160 | } 161 | 162 | pre, code { 163 | background-color: #f8f8f8; 164 | color: #333; 165 | } 166 | 167 | pre code { 168 | overflow: auto; 169 | word-wrap: normal; 170 | white-space: pre; 171 | } 172 | 173 | pre .img { 174 | margin: 5px 0; 175 | } 176 | 177 | pre .img img { 178 | background-color: #fff; 179 | display: block; 180 | height: auto; 181 | } 182 | 183 | code a, pre a { 184 | color: #375f84; 185 | } 186 | 187 | a.sourceLine:hover { 188 | text-decoration: none; 189 | } 190 | 191 | .fl {color: #1514b5;} 192 | .fu {color: #000000;} /* function */ 193 | .ch,.st {color: #036a07;} /* string */ 194 | .kw {color: #264D66;} /* keyword */ 195 | .co {color: #888888;} /* comment */ 196 | 197 | .message { color: black; font-weight: bolder;} 198 | .error { color: orange; font-weight: bolder;} 199 | .warning { color: #6A0366; font-weight: bolder;} 200 | 201 | /* Clipboard --------------------------*/ 202 | 203 | .hasCopyButton { 204 | position: relative; 205 | } 206 | 207 | .btn-copy-ex { 208 | position: absolute; 209 | right: 0; 210 | top: 0; 211 | visibility: hidden; 212 | } 213 | 214 | .hasCopyButton:hover button.btn-copy-ex { 215 | visibility: visible; 216 | } 217 | 218 | /* headroom.js ------------------------ */ 219 | 220 | .headroom { 221 | will-change: transform; 222 | transition: transform 200ms linear; 223 | } 224 | .headroom--pinned { 225 | transform: translateY(0%); 226 | } 227 | .headroom--unpinned { 228 | transform: translateY(-100%); 229 | } 230 | 231 | /* mark.js ----------------------------*/ 232 | 233 | mark { 234 | background-color: rgba(255, 255, 51, 0.5); 235 | border-bottom: 2px solid rgba(255, 153, 51, 0.3); 236 | padding: 1px; 237 | } 238 | 239 | /* vertical spacing after htmlwidgets */ 240 | .html-widget { 241 | margin-bottom: 10px; 242 | } 243 | 244 | /* fontawesome ------------------------ */ 245 | 246 | .fab { 247 | font-family: "Font Awesome 5 Brands" !important; 248 | } 249 | 250 | /* don't display links in code chunks when printing */ 251 | /* source: https://stackoverflow.com/a/10781533 */ 252 | @media print { 253 | code a:link:after, code a:visited:after { 254 | content: ""; 255 | } 256 | } 257 | -------------------------------------------------------------------------------- /docs/LICENSE-text.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | License • rasterly 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 60 | 61 | 62 | 63 | 64 | 65 | 66 |
    67 |
    68 | 114 | 115 | 116 | 117 |
    118 | 119 |
    120 |
    121 | 124 | 125 |
    YEAR: 2019
    126 | COPYRIGHT HOLDER: Plotly, Inc.
    127 | 
    128 | 129 |
    130 | 131 |
    132 | 133 | 134 | 135 |
    136 | 139 | 140 |
    141 |

    Site built with pkgdown 1.4.1.

    142 |
    143 | 144 |
    145 |
    146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Page not found (404) • rasterly 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 60 | 61 | 62 | 63 | 64 | 65 | 66 |
    67 |
    68 | 114 | 115 | 116 | 117 |
    118 | 119 |
    120 |
    121 | 124 | 125 | Content not found. Please use links in the navbar. 126 | 127 |
    128 | 129 |
    130 | 131 | 132 | 133 |
    134 | 137 | 138 |
    139 |

    Site built with pkgdown 1.4.1.

    140 |
    141 | 142 |
    143 |
    144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /man/rasterly_points.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rasterly_points.R 3 | \name{rasterly_points} 4 | \alias{rasterly_points} 5 | \title{rasterly_points} 6 | \usage{ 7 | rasterly_points( 8 | rastObj, 9 | data = NULL, 10 | mapping = aes(), 11 | ..., 12 | xlim = NULL, 13 | ylim = NULL, 14 | max_size = NULL, 15 | reduction_func = NULL, 16 | layout = NULL, 17 | glyph = NULL, 18 | group_by_data_table = NULL, 19 | inherit.aes = TRUE 20 | ) 21 | } 22 | \arguments{ 23 | \item{rastObj}{A \code{rasterly} object.} 24 | 25 | \item{data}{A \code{data.frame} or \code{function} with an argument \code{x}, specifying the dataset to use for plotting. If \code{data} 26 | is \code{NULL}, the \code{data} argument provided to \code{rasterly} may be passed through.} 27 | 28 | \item{mapping}{Default list of aesthetic mappings to use for plot. If provided and \code{inherit.aes = TRUE}, it will be 29 | stacked on top of the mappings passed to \code{rasterly}.} 30 | 31 | \item{...}{Pass-through arguments provided by \code{rasterly}.} 32 | 33 | \item{xlim}{Vector of type numeric. X limits in this layer.} 34 | 35 | \item{ylim}{Vector of type numeric. Y limits in this layer.} 36 | 37 | \item{max_size}{Numeric. When size changes, the upper bound of the number of pixels over which to spread a single observation.} 38 | 39 | \item{reduction_func}{Function. A reduction function is used to aggregate data points into their pixel representations. Currently 40 | supported reduction operators are \code{sum}, \code{any}, \code{mean}, \code{m2}, \code{first}, \code{last}, \code{min} and \code{max}. Default is \code{sum}. See details.} 41 | 42 | \item{layout}{Character. The method used to generate layouts for multiple images. The default is \code{weighted}. Useful for categorical 43 | data (i.e. "color" is provided via \code{aes()}). \code{weighted} specifies that the final raster should be a weighted combination of each 44 | (categorical) aggregation matrix. Conversely, \code{cover} indicates that the afterwards objects will be drawn on top of 45 | the previous ones.} 46 | 47 | \item{glyph}{Character. Currently, only "circle" and "square" are supported; as the \code{size} of the pixels increases, how should they 48 | spread out -- should the pattern be circular or square? Other glyphs may be added in the future.} 49 | 50 | \item{group_by_data_table}{Logical. Default is \code{TRUE}; when "color" is provided via \code{aes()}, the "group by" operation may be 51 | perfromed within \code{data.table} or natively within \code{rasterly}. Generally, \code{group_by_data_table = TRUE} is faster, but for very 52 | large datasets grouping within \code{rasterly} may offer better performance.} 53 | 54 | \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, rather than combining with them.} 55 | } 56 | \value{ 57 | A list of environments. 58 | } 59 | \description{ 60 | Points layer for \code{rasterly}. 61 | } 62 | \details{ 63 | Reduction functions 64 | \itemize{ 65 | \item{\code{sum}: If \code{on} is not provided within \code{aes()}, the default is to take the sum within each bin. 66 | When \code{on} is specified, the function reduces by taking the sum of all elements within the variable 67 | named in \code{on}.} 68 | \item{\code{any}: When \code{on} is provided within \code{aes()}, the \code{any} reduction function specifies whether any 69 | elements in \code{on} should be mapped to each bin.} 70 | \item{\code{mean}: If \code{on} is not provided in mapping \code{aes()}, \code{on} would be set as variable "y" by default. 71 | When \code{on} is given, the \code{mean} reduction function takes the mean of all elements within the variable 72 | specified by \code{on}.} 73 | \item{\code{m2}: Requires that \code{on} is specified within \code{aes()}. The \code{m2} function computes the sum of 74 | square differences from the mean of all elements in the variable specified by \code{on}.} 75 | \item{\code{var}: Requires that \code{on} is specified within \code{aes()}. The \code{var} function computes the variance 76 | over all elements in the vector specified by \code{on}.} 77 | \item{\code{sd}: Requires that \code{on} is specified within \code{aes()}. The \code{sd} function computes the standard 78 | deviation over all elements in the vector specified by \code{on}.} 79 | \item{\code{first}: Requires that \code{on} is specified within \code{aes()}. The \code{first} function returns the first 80 | element in the vector specified by \code{on}.} 81 | \item{\code{last}: Requires that \code{on} is specified within \code{aes()}. The \code{last} function returns the last 82 | element in the vector specified by \code{on}.} 83 | \item{\code{min}: Requires that \code{on} is specified within \code{aes()}. The \code{min} function returns the minimum 84 | value in the vector specified by \code{on}.} 85 | \item{\code{max}: Requires that \code{on} is specified within \code{aes()}. The \code{min} function returns the maximum 86 | value in the vector specified by \code{on}.} 87 | } 88 | } 89 | \examples{ 90 | \dontrun{ 91 | library(rasterly) 92 | if(requireNamespace("grid") && requireNamespace("gridExtra")) { 93 | x <- rnorm(1e7) 94 | y <- rnorm(1e7) 95 | category <- sample(1:5, 1e7, replace = TRUE) 96 | data.frame(x = x, y = y, category = category) \%>\% 97 | rasterly(mapping = aes(x = x, y = y, color = category)) \%>\% 98 | rasterly_points(layout = "weighted") -> ds1 99 | ds1 100 | # layout with cover 101 | data.frame(x = x, y = y, category = category) \%>\% 102 | rasterly(mapping = aes(x = x, y = y, color = category)) \%>\% 103 | rasterly_points(layout = "cover") -> ds2 104 | ds2 105 | # display side by side 106 | grid::grid.newpage() 107 | gridExtra::grid.arrange( 108 | grobs = list(rasterlyGrob(ds1), rasterlyGrob(ds2)), 109 | ncol = 2, 110 | top = "'weighted' layout versus 'cover' layout" 111 | ) 112 | } 113 | } 114 | } 115 | \seealso{ 116 | \link{rasterly}, \link{rasterly_build}, \link{[.rasterly}, \link{[<-.rasterly} 117 | } 118 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rasterly 2 | 3 | [![Build Status](https://travis-ci.org/z267xu/rasterly.svg?branch=master)](https://travis-ci.org/z267xu/rasterly) 4 | [![Codecov test coverage](https://codecov.io/gh/z267xu/rasterly/branch/master/graph/badge.svg)](https://codecov.io/gh/z267xu/rasterly?branch=master) 5 | [![CRAN status](https://www.r-pkg.org/badges/version/rasterly)](https://cran.r-project.org/web/packages/rasterly/index.html) 6 | [![](https://cranlogs.r-pkg.org/badges/rasterly)](https://cran.r-project.org/package=rasterly) 7 | 8 | Easily and rapidly generate raster data in R, even for larger volumes of data, with an aesthetics-based mapping syntax that should be familiar to users of the `ggplot2` package. 9 | 10 | 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. Combined with Plotly.js and the `plotly` package, `rasterly` enables analysts to generate interactive figures which are responsive enough to embed into web applications. 11 | 12 | Documentation: [https://z267xu.github.io/rasterly/](https://z267xu.github.io/rasterly/) 13 | 14 | ## Importing datasets for use with rasterly 15 | 16 | There are several ways to import large datasets into R for use with `rasterly`; one option is the `data.table` package (https://cran.r-project.org/web/packages/data.table/vignettes/datatable-intro.html). 17 | 18 | * csv file: 19 | ``` 20 | library(data.table) 21 | data <- data.table::fread("yourpath/somefile.csv") # or a link 22 | ``` 23 | 24 | * parquet file: 25 | Apache Parquet is a column-oriented, open-source format which offers efficient data compression. There are a few options in R for importing Parquet data. One of these is the [`arrow`](https://cran.r-project.org/web/packages/arrow/index.html) package, now available on CRAN. 26 | 27 | The package must build Apache Arrow first, so it may take a few minutes to install the first time around. 28 | 29 | ``` 30 | library(arrow) 31 | parquet_data <- read_parquet("somefile.parquet") 32 | # returns a data.frame if sparklyr is not loaded, otherwise it will be a tibble 33 | # to obtain an ordinary data.frame, some slight postprocessing may be required 34 | # parquet_data <- base::as.data.frame(parquet_data) 35 | ``` 36 | 37 | * fst file: 38 | The [fst package](https://www.fstpackage.org/) is an excellent option for extremely fast serialization of large data frames in R. In addition to rapid compression using LZ4 and ZSTD, it provides support for multithreading to parallelize operations. 39 | 40 | ``` 41 | library(fst) 42 | fst_data <- read.fst("somefile.fst") 43 | ``` 44 | 45 | ## Installing the package 46 | 47 | The `rasterly` package is now available from CRAN, and the most recent release will always be available on GitHub. To install the CRAN package: 48 | ``` 49 | install.packages("rasterly") 50 | ``` 51 | To install the current version available via GitHub instead: 52 | ``` 53 | remotes::install_github("plotly/rasterly") 54 | ``` 55 | 56 | ## Visualizing data with `rasterly` 57 | 58 | `rasterly` is inspired by the [`datashader`](http://datashader.org/getting_started/index.html) package available for Python. Both provide the capability to generate raster data for rapid rendering of graphics for even very large datasets. 59 | 60 | In terms of performance, `datashader` is faster but `rasterly` is comparable. `rasterly` aims to provide a user-friendly interface to generate raster data for use with the `plotly` package; it cannot be used for plotting or rendering figures on its own. 61 | 62 | #### Producing an interactive graph with the plotly package 63 | 64 | To illustrate the basic functionality provided by the package, we'll start by retrieving data on Uber trips taken in New York City from April 1st until September 30th of 2014. The dataset includes 4,533,327 observations. 65 | 66 | ``` 67 | # Load New York Uber data 68 | ridesRaw_1 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data1.csv" %>% 69 | data.table::fread(stringsAsFactors = FALSE) 70 | ridesRaw_2 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data2.csv" %>% 71 | data.table::fread(stringsAsFactors = FALSE) 72 | ridesRaw_3 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data3.csv" %>% 73 | data.table::fread(stringsAsFactors = FALSE) 74 | ridesDf <- list(ridesRaw_1, ridesRaw_2, ridesRaw_3) %>% 75 | data.table::rbindlist() 76 | ``` 77 | 78 | Now that the data are loaded, we can pass them to `plot_ly` and pipe the output into `add_rasterly`: 79 | 80 | ``` 81 | plot_ly(ridesDf, x = ~Lat, y = ~Lon) %>% 82 | add_rasterly_heatmap() 83 | ``` 84 | ![](man/figures/add_rasterizer.gif) 85 | 86 | #### General usage 87 | 88 | Pass the data into `rasterly`: 89 | ``` 90 | ridesDf %>% 91 | rasterly(mapping = aes(x = Lat, y = Lon)) %>% 92 | rasterly_points() -> p 93 | p 94 | # or use simplied `rplot` 95 | with(ridesDf, 96 | rplot(x = Lat, y = Lon) 97 | ) 98 | ``` 99 | ![](man/figures/grid_rasterizer.png) 100 | 101 | Note that, `p` is a list of environments. The display info can be accessed through 102 | ``` 103 | r <- rasterly_build(p) 104 | str(r) 105 | ``` 106 | 107 | "r" contains image raster and other useful info (like numeric aggregation matrices) required to produce the image but it does **not** provide any graphs. 108 | 109 | ## Example use in interactive web applications 110 | 111 | The Uber NYC Rasterizer application in our Dash Gallery provides a simple live demo of the `rasterly` package in action. Check it out [here](https://dash-gallery.plotly.host/dashr-uber-rasterizer/)! 112 | 113 | Uber NYC Rasterizer screenshot 114 | 115 | A second [Dash for R](https://github.com/plotly/dashR) application to visualize (a much larger) dataset from the US Census Bureau is also [available](https://github.com/plotly/rasterly/tree/master/apps/UScensus). 116 | -------------------------------------------------------------------------------- /docs/articles/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Articles • rasterly 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 60 | 61 | 62 | 63 | 64 | 65 | 66 |
    67 |
    68 | 114 | 115 | 116 | 117 |
    118 | 119 |
    120 |
    121 | 124 | 125 |
    126 |

    All vignettes

    127 |

    128 | 129 | 132 |
    133 |
    134 |
    135 | 136 | 137 |
    138 | 141 | 142 |
    143 |

    Site built with pkgdown 1.4.1.

    144 |
    145 | 146 |
    147 |
    148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /docs/authors.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Authors • rasterly 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 60 | 61 | 62 | 63 | 64 | 65 | 66 |
    67 |
    68 | 114 | 115 | 116 | 117 |
    118 | 119 |
    120 |
    121 | 124 | 125 |
      126 |
    • 127 |

      Zehao Xu. Author, maintainer. 128 |

      129 |
    • 130 |
    • 131 |

      Ryan Patrick Kyle. Contributor. ORCID 132 |

      133 |
    • 134 |
    • 135 |

      Plotly Technologies. Copyright holder. 136 |

      137 |
    • 138 |
    139 | 140 |
    141 | 142 |
    143 | 144 | 145 | 146 |
    147 | 150 | 151 |
    152 |

    Site built with pkgdown 1.4.1.

    153 |
    154 | 155 |
    156 |
    157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /man/static.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot.R 3 | \name{static} 4 | \alias{static} 5 | \alias{rasterlyGrob} 6 | \alias{grid.rasterly} 7 | \alias{plot.rasterly} 8 | \alias{print.rasterly} 9 | \title{Annotate and customize rasterly figures} 10 | \usage{ 11 | rasterlyGrob( 12 | rasterlyObj, 13 | xlim = NULL, 14 | ylim = NULL, 15 | xlab = NULL, 16 | ylab = NULL, 17 | main = NULL, 18 | sub = NULL, 19 | interpolate = FALSE, 20 | axes = TRUE, 21 | legend = TRUE, 22 | legend_label = NULL, 23 | legend_layer = 1, 24 | legend_main = NULL, 25 | axes_gpar = grid::gpar(col = "black", cex = 1), 26 | label_gpar = grid::gpar(col = "black", cex = 1), 27 | main_gpar = grid::gpar(col = "black", cex = 1.5), 28 | legend_gpar = grid::gpar(col = "black", cex = 1.5), 29 | name = NULL, 30 | gp = NULL, 31 | vp = NULL 32 | ) 33 | 34 | grid.rasterly( 35 | rasterlyObj, 36 | interpolate = FALSE, 37 | axes = TRUE, 38 | xlim = NULL, 39 | ylim = NULL, 40 | xlab = NULL, 41 | ylab = NULL, 42 | main = NULL, 43 | sub = NULL, 44 | legend = TRUE, 45 | legend_label = NULL, 46 | legend_layer = 1, 47 | legend_main = NULL, 48 | axes_gpar = grid::gpar(col = "black", cex = 1), 49 | label_gpar = grid::gpar(col = "black", cex = 1), 50 | main_gpar = grid::gpar(col = "black", cex = 1.5), 51 | legend_gpar = grid::gpar(col = "black", cex = 1.5), 52 | name = NULL, 53 | gp = NULL, 54 | vp = NULL, 55 | ... 56 | ) 57 | 58 | \method{plot}{rasterly}( 59 | x, 60 | y = NULL, 61 | xlim = NULL, 62 | ylim = NULL, 63 | xlab = NULL, 64 | ylab = NULL, 65 | main = NULL, 66 | legend_main = NULL, 67 | sub = NULL, 68 | interpolate = FALSE, 69 | axes = TRUE, 70 | legend = TRUE, 71 | legend_label = NULL, 72 | legend_layer = 1, 73 | new.page = TRUE, 74 | ... 75 | ) 76 | 77 | \method{print}{rasterly}(x, ...) 78 | } 79 | \arguments{ 80 | \item{rasterlyObj}{A \code{rasterly} object.} 81 | 82 | \item{xlim}{Numeric; the x limits (x1, x2) of the plot. Default is \code{NULL}.} 83 | 84 | \item{ylim}{Numeric; the y limits (y1, y2) of the plot. Default is \code{NULL}.} 85 | 86 | \item{xlab}{Character; the label to be used for the \code{x} axis. Default is \code{NULL}.} 87 | 88 | \item{ylab}{Character; the label to be used for the \code{y} axis. Default is \code{NULL}.} 89 | 90 | \item{main}{Character; the title to be used for the plot. Default is \code{NULL}.} 91 | 92 | \item{sub}{sub Character; a subtitle for the plot. Default is \code{NULL}.} 93 | 94 | \item{interpolate}{Logical. Linearly interpolates the image if \code{TRUE}. Default is \code{FALSE}.} 95 | 96 | \item{axes}{Logical; should axes be drawn? Default is \code{TRUE}, set to \code{FALSE} to hide axes.} 97 | 98 | \item{legend}{Logical. Show a figure legend? Default is \code{TRUE}; set to \code{FALSE} to hide the legend.} 99 | 100 | \item{legend_label}{Character. The label to apply to the figure legend. Default is \code{NULL}, which omits the figure legend label.} 101 | 102 | \item{legend_layer}{Numeric. Specify the layer level within the \code{rasterly} object. The default layer level is `1`, which represents the uppermost layer.} 103 | 104 | \item{legend_main}{Character. The main title to use within the figure legend. The default is \code{NULL}, which omits the figure legend title.} 105 | 106 | \item{axes_gpar}{Object of class \code{gpar}. This graphical parameter (\code{\link{gpar}}) controls axis color, size, and other aesthetics.} 107 | 108 | \item{label_gpar}{Object of class \code{gpar}. This graphical parameter (\code{\link{gpar}}) controls label color, size, and other aesthetics.} 109 | 110 | \item{main_gpar}{Object of class \code{gpar}. This graphical parameter (\code{\link{gpar}}) controls the main title's color, size, and other aesthetics.} 111 | 112 | \item{legend_gpar}{Object of class \code{gpar}. This graphical parameter (\code{\link{gpar}}) controls the legend's color, size, and other aesthetics.} 113 | 114 | \item{name}{Character. An identifier used to locate the \code{\link{grob}} within the display list and/or as a child of another grob.} 115 | 116 | \item{gp}{A \code{\link{gpar}} object, typically the output from a call to the function \code{grid::gpar}. This argument represents a list of graphical parameter settings.} 117 | 118 | \item{vp}{Object of class \code{\link{viewport}}. If provided, \code{\link{rasterlyGrob}} will pass this argument through to \code{grob}. Default is \code{NULL}.} 119 | 120 | \item{...}{Other arguments to modify the display.} 121 | 122 | \item{x}{A \code{rasterly} object} 123 | 124 | \item{y}{NULL, will be ignored.} 125 | 126 | \item{new.page}{display on a new page or not.} 127 | } 128 | \description{ 129 | Create a static plot based on \code{rasterly} object. 130 | This function allows users to add axes, legends and other descriptive details when generating `rasterly` objects. 131 | } 132 | \details{ 133 | We provide three functions to produce static graphics, which is based on the API of \code{grid}, \code{plot} and \code{print}. 134 | \itemize{ 135 | \item{\code{grid}: The \code{rasterlyGrob} and \code{grid.rasterly} are the most flexible data structure. 136 | These functions produce a **\code{grob}** object. Users can modify the existing display by the functions provided by \code{grid}}. 137 | \item{\code{plot.rasterly}: The usage of this S3 method is very similar to the classic \code{\link{plot}} function. 138 | Users can set axis limits via \code{xlim} and \code{ylim}, as well as the corresponding labels using \code{xlab} and \code{ylab}, among other attributes.} 139 | \item{\code{print.rasterly}: This S3 method returns only a basic image raster.} 140 | } 141 | } 142 | \examples{ 143 | if(requireNamespace("grid")) { 144 | data <- data.frame(x = rnorm(1e6), 145 | y = rexp(1e6, 10)) 146 | # a rasterly object 147 | rasterlyObj <- data \%>\% 148 | rasterly(mapping = aes(x = x, y = y)) \%>\% 149 | rasterly_points() 150 | # Generate a grob 151 | rg <- rasterlyGrob(rasterlyObj) 152 | ## get the raster grob by `grid::getGrob()` 153 | grid::getGrob(rg, "raster") 154 | grid::grid.newpage() 155 | grid::grid.draw(rg) 156 | # or 157 | grid::grid.newpage() 158 | grid.rasterly(rasterlyObj) 159 | # or `plot` 160 | plot(rasterlyObj, xlab = "rnorm(1e6)", 161 | ylab = "rexp(1e6, 10)", 162 | main = "This is an arbitrary plot") 163 | # or simply print 164 | rasterlyObj 165 | ## it is equivalent to `print(rasterlyObj)` 166 | } 167 | 168 | } 169 | \seealso{ 170 | \code{\link{plotRasterly}}, \code{\link{ggRasterly}} 171 | } 172 | -------------------------------------------------------------------------------- /docs/reference/reexports.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Objects exported from other packages — reexports • rasterly 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 68 | 69 | 70 | 71 | 72 | 73 | 74 |
    75 |
    76 | 122 | 123 | 124 | 125 |
    126 | 127 |
    128 |
    129 | 134 | 135 |
    136 |

    These objects are imported from other packages. Follow the links 137 | below to see their documentation.

    138 |
    139 |
    ggplot2

    aes

    140 | 141 |
    magrittr

    %>%

    142 | 143 |
    144 |
    145 | 146 | 147 | 148 | 149 |
    150 | 156 |
    157 | 158 | 159 |
    160 | 163 | 164 |
    165 |

    Site built with pkgdown 1.4.1.

    166 |
    167 | 168 |
    169 |
    170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | -------------------------------------------------------------------------------- /docs/reference/is.rasterly.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Is <code>rasterly</code> — is.rasterly • rasterly 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 61 | 62 | 63 | 64 | 65 | 66 | 67 |
    68 |
    69 | 115 | 116 | 117 | 118 |
    119 | 120 |
    121 |
    122 | 127 | 128 |
    129 |

    Reports whether x is a rasterly object.

    130 |
    131 | 132 |
    is.rasterly(x)
    133 | 134 |

    Arguments

    135 | 136 | 137 | 138 | 139 | 140 | 141 |
    x

    a rasterly object

    142 | 143 | 144 |
    145 | 152 |
    153 | 154 | 155 |
    156 | 159 | 160 |
    161 |

    Site built with pkgdown 1.4.1.

    162 |
    163 | 164 |
    165 |
    166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /docs/reference/color_map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Supplemental color maps for rasterly — color_map • rasterly 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |
    69 |
    70 | 116 | 117 | 118 | 119 |
    120 | 121 |
    122 |
    123 | 128 | 129 |
    130 |

    Hex codes for the color map. 131 | Used in setting argument color in rasterly or rasterly layers.

    132 |
    133 | 134 |
    fire_map
    135 | 
    136 | viridis_map
    137 | 
    138 | hourColors_map
    139 | 140 | 141 |

    Format

    142 | 143 |

    An object of class character of length 256.

    144 |

    An object of class character of length 256.

    145 |

    An object of class character of length 24.

    146 | 147 |
    148 | 155 |
    156 | 157 | 158 |
    159 | 162 | 163 |
    164 |

    Site built with pkgdown 1.4.1.

    165 |
    166 | 167 |
    168 |
    169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /R/rasterly.R: -------------------------------------------------------------------------------- 1 | #' Easily and rapidly generate raster image data with support for Plotly.js 2 | #' @description Create a rasterly object, to which aggregation layers may be added. This function is the first step in the process 3 | #' to generate raster image data using the \code{rasterly} package. 4 | #' @param data Dataset to use for generating the plot. If not provided, data must be supplied in each layer of the plot. 5 | #' For best performance, particularly when processing large datasets, use of \link[data.table]{data.table} is recommended. 6 | #' @param mapping Default list of aesthetic mappings to use for plot. The same with \code{ggplot2} \link[ggplot2]{aes}. 7 | #' See details. 8 | #' @param ... Other arguments which will be passed through to layers. 9 | #' @param plot_width Integer. The width of the image to plot; must be a positive integer. A higher value indicates a higher resolution. 10 | #' @param plot_height Integer. The height of the image to plot; must be a positive integer. A higher value indicates a higher resolution. 11 | #' @param x_range Vector of type numeric. The range of \code{x}; it can be used to clip the image. For larger datasets, providing \code{x_range} 12 | #' may result in improved performance. 13 | #' @param y_range Vector of type numeric. The range of \code{y}; it can be used to clip the image. For larger datasets, providing \code{y_range} 14 | #' may result in improved performance. 15 | #' @param background Character. The background color of the image to plot. 16 | #' @param color Vector of type character. It will determine this color vector is a \code{color_map} or \code{color_key} automatically. 17 | #' \itemize{ 18 | #' \item{}{color_map: It has Color(s) used to draw each pixel. The \code{color_map} is extended by linear interpolation 19 | #' independently for RGB. The darkness of the mapped color depends upon the values of the aggregation matrix. 20 | #' } 21 | #' \item{}{color_key: Vector of type character. The \code{color_key} is used for categorical variables; 22 | #' it is passed when the \code{color} aesthetic is provided. 23 | #' } 24 | #' } 25 | #' @param show_raster Logical. Should the raster be displayed? 26 | #' @param drop_data Logical. When working with large datasets, drops the original data once processed according to the provided 27 | #' \code{aes()} parameters, using the \code{remove()} function. See details for additional information. 28 | #' @param variable_check Logical. If \code{TRUE}, drops unused columns to save memory; may result in reduced performance. 29 | #' 30 | #' @return An environment wrapped by a list which defines the properties of the raster data to be generated. 31 | #' 32 | #' @note Calling \code{rasterly()} without providing \code{rasterly_...()} layers has no effect. 33 | #' More info can be found in \href{https://github.com/plotly/rasterly/blob/master/README.md}{README.md} 34 | #' 35 | #' @seealso \link{rasterly_points}, \link{rasterly_build}, \link{[.rasterly}, \link{[<-.rasterly} 36 | #' \link{ggRasterly}, \link{plotRasterly} 37 | #' @details 38 | #' \itemize{ 39 | #' \item{}{The rasterly package currently supports five aesthetics via \code{aes()}: \code{x}, \code{y}, \code{on}, \code{color}, and \code{size}. 40 | #' The "on" aesthetic specifies the variable upon which the reduction function should be applied to generate the raster data. 41 | #' } 42 | #' \item{}{\code{drop_data} can help save space, particularly when large datasets are used. However, dropping the original dataset 43 | #' may result in errors when attempting to set or update \code{aes()} parameters within rasterly layers. 44 | #' } 45 | #' } 46 | #' 47 | #' @examples 48 | #' \dontrun{ 49 | #' if(requireNamespace("data.table")) { 50 | #' url1 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data1.csv" 51 | #' ridesRaw_1 <- url1 %>% 52 | #' data.table::fread(stringsAsFactors = FALSE) 53 | #' url2 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data2.csv" 54 | #' ridesRaw_2 <- url2 %>% 55 | #' data.table::fread(stringsAsFactors = FALSE) 56 | #' url3 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data3.csv" 57 | #' ridesRaw_3 <- url3 %>% 58 | #' data.table::fread(stringsAsFactors = FALSE) 59 | #' ridesDf <- list(ridesRaw_1, ridesRaw_2, ridesRaw_3) %>% 60 | #' data.table::rbindlist() 61 | #' 62 | #' ridesDf %>% 63 | #' rasterly(mapping = aes(x = Lat, y = Lon)) %>% 64 | #' rasterly_points() 65 | #' }} 66 | #' 67 | #' @useDynLib rasterly 68 | #' @import Rcpp 69 | #' @import rlang 70 | #' @import methods 71 | #' @importFrom grDevices rgb col2rgb hcl extendrange as.raster 72 | #' @importFrom magrittr '%>%' 73 | #' @importFrom stats ecdf approx setNames na.omit 74 | #' @importFrom ggplot2 aes 75 | #' @importFrom data.table data.table 76 | #' @export 77 | rasterly <- function(data = NULL, 78 | mapping = aes(), 79 | ..., 80 | plot_width = 600, plot_height = 600, 81 | x_range = NULL, y_range = NULL, 82 | background = "white", 83 | color = NULL, 84 | show_raster = TRUE, 85 | drop_data = FALSE, 86 | variable_check = FALSE) { 87 | mapping <- rename_mapping(mapping) 88 | 89 | stopifnot( 90 | exprs = { 91 | is.numeric(plot_width) && plot_width > 0 92 | is.numeric(plot_height) && plot_height > 0 93 | } 94 | ) 95 | plot_width <- round(plot_width) 96 | plot_height <- round(plot_height) 97 | 98 | if(!is.null(x_range)) { 99 | stopifnot( 100 | exprs = { 101 | length(x_range) == 2 && is.numeric(x_range) 102 | } 103 | ) 104 | } 105 | 106 | if(!is.null(y_range)) { 107 | stopifnot( 108 | exprs = { 109 | length(y_range) == 2 && is.numeric(y_range) 110 | } 111 | ) 112 | } 113 | 114 | if(!is.null(data) && !rlang::is_empty(mapping)) { 115 | aesthetics <- get_aesthetics(data, mapping, variable_check, ...) 116 | range <- get_range(x_range = x_range, 117 | y_range = y_range, 118 | x = aesthetics$x, 119 | y = aesthetics$y) 120 | x_range <- range$x_range 121 | y_range <- range$y_range 122 | 123 | if(drop_data) { 124 | remove(data) 125 | message("drop_data is TRUE; removing the source dataset. Attempts to pass new aes() parameters to layers may generate an error.") 126 | } 127 | } 128 | 129 | # make sure all arguments exist in `rasterly` environment 130 | args <- list(...) 131 | if(!is.null(args$color_map)) { 132 | warning("`color_map` is deprecated now. Please use `color` instead.", call. = FALSE) 133 | color_map <- args$color_map 134 | color <- color_map 135 | } 136 | if(!is.null(args$color_key)) { 137 | warning("`color_key` is deprecated now. Please use `color` instead.", call. = FALSE) 138 | color_key <- args$color_key 139 | color <- color_key 140 | } 141 | if(!is.null(args$col)) color <- args$col 142 | 143 | rastObj <- structure( 144 | list( 145 | rasterly_env = environment() 146 | ), 147 | class = c("rasterly") 148 | ) 149 | invisible(return(rastObj)) 150 | } 151 | -------------------------------------------------------------------------------- /docs/reference/is.rasterlyBuild.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Is <code>rasterlyBuild</code> — is.rasterlyBuild • rasterly 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |
    69 |
    70 | 116 | 117 | 118 | 119 |
    120 | 121 |
    122 |
    123 | 128 | 129 |
    130 |

    Reports whether x is a rasterlyBuild object. In other word, it helps to define 131 | whether this object has been passed through `rasterly_build`

    132 |
    133 | 134 |
    is.rasterlyBuild(x)
    135 | 136 |

    Arguments

    137 | 138 | 139 | 140 | 141 | 142 | 143 |
    x

    a rasterly object

    144 | 145 | 146 |
    147 | 154 |
    155 | 156 | 157 | 167 |
    168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /R/add_rasterly_heatmap.R: -------------------------------------------------------------------------------- 1 | #' @title Add "rasterly" trace to a Plotly visualization 2 | #' @name add_rasterly 3 | #' @description Add trace to a Plotly visualization. 4 | #' @param p A \code{plotly} object 5 | #' @param x Numeric vector or expression. The x variable, to be passed on to \code{aes()}. 6 | #' @param y Numeric or expression. The y variable, to be passed on to \code{aes()}. 7 | #' @param z Numeric. A numeric matrix (optional), to be processed with \code{add_heatmap}. 8 | #' @param data A data.frame or \link[crosstalk]{SharedData} object (optional). 9 | #' @param inherit Logical. Inherit attributes from \link[plotly]{plotly}? 10 | #' @param on Numeric vector or expression. Provides the data on which to reduce, to be passed on to \code{aes()}. 11 | #' @param size Numeric vector or expression. Pixel size for each observation, to be passed on to \code{aes()}. 12 | #' @param scaling Character string or function. The scaling method to be used for the trace. 13 | #' @param ... Arguments (i.e., attributes) passed along to the trace type or \code{rasterly}. 14 | #' @export 15 | #' 16 | #' @examples 17 | #' \dontrun{ 18 | #'if(requireNamespace("plotly") && requireNamespace("data.table") && 19 | #' requireNamespace("lubridate")) { 20 | #' # Load data 21 | #' url1 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data1.csv" 22 | #' ridesRaw_1 <- url1 %>% 23 | #' data.table::fread(stringsAsFactors = FALSE) 24 | #' url2 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data2.csv" 25 | #' ridesRaw_2 <- url2 %>% 26 | #' data.table::fread(stringsAsFactors = FALSE) 27 | #' url3 <- "https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data3.csv" 28 | #' ridesRaw_3 <- url3 %>% 29 | #' data.table::fread(stringsAsFactors = FALSE) 30 | #' ridesDf <- list(ridesRaw_1, ridesRaw_2, ridesRaw_3) %>% 31 | #' data.table::rbindlist() 32 | #' time <- lubridate::ymd_hms(ridesDf$`Date/Time`) 33 | #' ridesDf <- ridesDf[, 'Date/Time':=NULL][, list(Lat, 34 | #' Lon, 35 | #' hour = lubridate::hour(time), 36 | #' month = lubridate::month(time), 37 | #' day = lubridate::day(time))] 38 | #' ############################# add_rasterly_heatmap ############################# 39 | #' #### quick start 40 | #' p <- plot_ly(data = ridesDf) %>% 41 | #' add_rasterly_heatmap(x = ~Lat, y = ~Lon) 42 | #' p 43 | #' #### set artificial scaling function 44 | #' zeroOneTransform <- function(z) { 45 | #' minz <- min(z) 46 | #' maxz <- max(z) 47 | #' M <- matrix((z - minz)/(maxz - minz), nrow = dim(z)[1]) 48 | #' return(M) 49 | #' } 50 | #' plot_ly(data = ridesDf) %>% 51 | #' add_rasterly_heatmap(x = ~Lat, 52 | #' y = ~Lon, 53 | #' on = ~-Lat, 54 | #' reduction_func = "max", 55 | #' scaling = zeroOneTransform) %>% 56 | #' plotly::layout( 57 | #' xaxis = list( 58 | #' title = "x" 59 | #' ), 60 | #' yaxis = list( 61 | #' title = "y" 62 | #' ) 63 | #' ) 64 | #' ############################# add_rasterly_image ############################# 65 | #' p <- plot_ly(data = ridesDf) %>% 66 | #' add_rasterly_image(x = ~Lat, y = ~Lon, color = ~hour, 67 | #' # even `color_map` is deprecated, 68 | #' # it is still a good way to specify the color mapping 69 | #' color_map = hourColors_map, 70 | #' plot_width = 400, plot_height = 400) 71 | #' p 72 | #' } 73 | #' } 74 | add_rasterly_heatmap <- function(p, 75 | x = NULL, y = NULL, z = NULL, ..., 76 | data = NULL, inherit = TRUE, 77 | on = NULL, size = NULL, 78 | scaling = NULL) { 79 | if (inherit) { 80 | x <- x %||% p$x$attrs[[1]][["x"]] 81 | y <- y %||% p$x$attrs[[1]][["y"]] 82 | z <- z %||% p$x$attrs[[1]][["z"]] 83 | } 84 | 85 | args <- list(...) 86 | rasterly_args <- c( 87 | union(methods::formalArgs(rasterly), methods::formalArgs(rasterly_points)), 88 | "color_map", 89 | "colour_map", 90 | "color_key", 91 | "colour_key" 92 | ) 93 | args[rasterly_args] <- NULL 94 | 95 | if (is.null(z)) { 96 | # produce z by rasterly 97 | ### set vars 98 | data <- data %||% p$x$visdat[[1]]() 99 | on <- on %||% p$x$attrs[[1]][["on"]] 100 | size <- size %||% p$x$attrs[[1]][["size"]] 101 | 102 | ### set mappings 103 | mapping_names <- c("x", "y", "on", "size") 104 | names(mapping_names) <- mapping_names 105 | mapping <- aes() 106 | expressions <- stats::setNames( 107 | list(x, y, on, size), 108 | mapping_names 109 | ) 110 | 111 | for(i in 1:length(mapping_names)) { 112 | exp <- expressions[[i]] 113 | 114 | if(is.null(exp)) { 115 | mapping_names[i] <- NA 116 | } else { 117 | if(rlang::is_formula(exp)) { 118 | the_parse <- sub("~", "", rlang::expr_text(exp)) %>% 119 | rlang::parse_expr() 120 | mapping[[i]] <- rlang::quo(!!the_parse) 121 | } else if(is.numeric(exp)) { 122 | data[[mapping_names[i]]] <- exp 123 | mapping[[i]] <- rlang::quo(!!rlang::parse_expr(mapping_names[i])) 124 | } else { 125 | stop("'size' ,'on' are neither `quote` nor a numerical value.", call. = FALSE) 126 | } 127 | } 128 | } 129 | 130 | mapping <- Filter(Negate(is.null), mapping) 131 | names(mapping) <- stats::na.omit(mapping_names) 132 | 133 | data %>% 134 | rasterly(mapping = mapping, 135 | show_raster = FALSE, 136 | ...) %>% 137 | rasterly_points() %>% 138 | rasterly_build() -> rastObj 139 | data <- NULL 140 | if(sum(lengths(rastObj$agg)) > 1) 141 | message("More than one aggregation matrix was detected.") 142 | 143 | z <- rastObj$agg[[1]][[1]] 144 | dimZ <- dim(z) 145 | y <- seq(rastObj$y_range[1], rastObj$y_range[2], length.out = dimZ[1]) 146 | x <- seq(rastObj$x_range[1], rastObj$x_range[2], length.out = dimZ[2]) 147 | remove(rastObj) 148 | 149 | scaling <- scaling %||% { 150 | message("The default scaling is 'log'.") 151 | "log" 152 | } 153 | if(is.function(scaling)) { 154 | z <- do.call(scaling, 155 | list(z = z)) 156 | } else { 157 | if(!is.character(scaling)) stop("'scaling' must either be an R function or a character string.") 158 | switch(scaling, 159 | "log" = { 160 | z <- matrix(log(z + 1), nrow = dimZ[1]) 161 | }, 162 | "origin" = NULL) 163 | } 164 | } else message("If z is provided, `plotly::add_heatmap` will be implemented.") 165 | 166 | do.call( 167 | add_trace_classed, 168 | c( 169 | list( 170 | p = p, 171 | class = "plotly_heatmap", 172 | z = z, 173 | x = x, 174 | y = y, 175 | type = "heatmap", 176 | data = data, 177 | inherit = inherit 178 | ), 179 | args 180 | ) 181 | ) 182 | } 183 | --------------------------------------------------------------------------------