From 80008f540887b11edec4e605688a8852515ac64a Mon Sep 17 00:00:00 2001 From: Carson Sievert Date: Thu, 31 May 2018 12:27:59 -0500 Subject: [PATCH 1/3] start on a proper wrapper around orca --- DESCRIPTION | 3 +- NAMESPACE | 1 + R/export.R | 18 +++++------ R/orca.R | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++ man/export.Rd | 13 +------- man/orca.Rd | 53 +++++++++++++++++++++++++++++++ 6 files changed, 151 insertions(+), 24 deletions(-) create mode 100644 R/orca.R create mode 100644 man/orca.Rd diff --git a/DESCRIPTION b/DESCRIPTION index de7cfc8421..4dcae48bc0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -67,7 +67,8 @@ Suggests: rgeos, RSelenium, png, - IRdisplay + IRdisplay, + processx Remotes: tidyverse/ggplot2 LazyData: true diff --git a/NAMESPACE b/NAMESPACE index 5bebe64d20..c6b0f07969 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -149,6 +149,7 @@ export(layout) export(mutate) export(mutate_) export(offline) +export(orca) export(partial_bundle) export(plot_dendro) export(plot_geo) diff --git a/R/export.R b/R/export.R index 213b44d161..397348fd99 100644 --- a/R/export.R +++ b/R/export.R @@ -1,5 +1,7 @@ #' Export a plotly graph to a static file #' +#' This function is in the process of being deprecated. Use the `[orca]()` function instead. +#' #' @details For SVG plots, a screenshot is taken via `webshot::webshot()`. #' Since `phantomjs` (and hence `webshot`) does not support WebGL, #' the RSelenium package is used for exporting WebGL plots. @@ -21,17 +23,6 @@ #' export(plot_ly(economics, x = ~date, y = ~pce)) #' export(plot_ly(economics, x = ~date, y = ~pce), "plot.pdf") #' -#' # svg/webp output or WebGL conversion can be done via RSelenium -#' if (requireNamespace("RSelenium")) { -#' rD <- RSelenium::rsDriver(browser = "chrome") -#' export( -#' plot_ly(economics, x = ~date, y = ~pce), "plot.svg", rD -#' ) -#' export( -#' plot_ly(economics, x = ~date, y = ~pce, z = ~pop), "yay.svg", rD -#' ) -#' } -#' #' # If you can't get a selenium server running, another option is to #' # use Plotly.downloadImage() via htmlwidgets::onRender()... #' # Downloading images won't work inside RStudio, but you can set the viewer @@ -46,6 +37,11 @@ #' ) #'} export <- function(p = last_plot(), file = "plotly.png", selenium = NULL, ...) { + message( + "The `export()` function is in the process of being deprecated. ", + "Please use the `orca()` function instead." + ) + # infer the file type fileType <- tolower(tools::file_ext(file)) if (!fileType %in% c('jpeg', 'png', 'webp', 'svg', 'pdf')) { diff --git a/R/orca.R b/R/orca.R new file mode 100644 index 0000000000..be8f1f5936 --- /dev/null +++ b/R/orca.R @@ -0,0 +1,87 @@ +#' Static image export via orca +#' +#' The function requires the orca command-line utility, +#' see the installation instructions [here](https://github.com/plotly/orca#installation) +#' +#' @param p a plotly object. +#' @param file output filename. +#' @param format the output format (png, jpeg, webp, svg, pdf, eps). +#' @param scale Sets the image scale. Applies to all output images. +#' @param width Sets the image width. If not set, defaults to `layout.width` value. +#' Applies to all output images. +#' @param height Sets the image height. If not set, defaults to `layout.height` value. +#' Applies to all output images. +#' @param mathjax whether or not to specify a path to mathjax (required to export LaTeX characters). +#' This should 'just work' in RStudio, but outside RStudio, you may have to set +#' the PLOTLY_MATHJAX_PATH environment variable to the location of MathJax. +#' @param parallel_limit Sets the limit of parallel tasks run. +#' @param verbose Turn on verbose logging on stdout. +#' @param debug Starts app in debug mode and turn on verbose logs on stdout. +#' @param safe Turns on safe mode: where figures likely to make browser window +#' hang during image generating are skipped. +#' @export +#' @author Carson Sievert +#' @examples +#' +#' p <- plot_ly(z = ~volcano) %>% add_surface() +#' orca(p, "surface-plot.png") +#' orca(p, "surface-plot.svg") +#' orca(p, "surface-plot.pdf") +#' + +orca <- function(p, file = "plot.png", format = tools::file_ext(file), + scale = NULL, width = NULL, height = NULL, mathjax = FALSE, + parallel_limit = NULL, verbose = FALSE, debug = FALSE, + safe = FALSE) { + + if (Sys.which("orca") == "") { + stop( + "The orca command-line utility is required to use the `orca()` function.\n\n", + "Follow the installation instructions here -- https://github.com/plotly/orca#installation", + call. = FALSE + ) + } + + b <- plotly_build(p) + + # find the relevant plotly.js bundle + plotlyjs <- plotlyjsBundle(b) + plotlyjs_file <- file.path(plotlyjs$src$file, plotlyjs$script) + + args <- c( + "graph", plotly:::to_JSON(b$x[c("data", "layout")]), + "-o", file, + "--format", format, + "--plotlyjs", plotlyjs_file, + if (debug) "--debug", + if (verbose) "--verbose", + if (safe) "--safe-mode" + ) + + if (!is.null(scale)) args <- c(args, "--scale", scale) + if (!is.null(width)) args <- c(args, "--width", width) + if (!is.null(height)) args <- c(args, "--height", height) + if (!is.null(parallel_limit)) args <- c(args, "--parallel-limit", parallel_limit) + if (!is.na(mapbox_token())) args <- c(args, "--mapbox-access-token", mapbox_token()) + if (isTRUE(mathjax)) args <- c(args, "--mathjax", mathjax_path()) + + # TODO: point to local topojson? Should this only work if plot_geo(standalone = TRUE)? + try_library("processx", "orca") + invisible(processx::run("orca", args, echo = TRUE, spinner = TRUE)) +} + + +mathjax_path <- function() { + if (is_rstudio()) { + try_library("rmarkdown", "orca") + return(getFromNamespace("pandoc_mathjax_local_path", "rmarkdown")()) + } + path <- Sys.getenv("PLOTLY_MATHJAX_PATH", Sys.getenv("RMARKDOWN_MATHJAX_PATH", NA)) + if (!is.na(path)) return(normalizePath(path, mustWork = TRUE)) + stop( + "Please set either the RMARKDOWN_MATHJAX_PATH or PLOTLY_MATHJAX_PATH ", + "environment variable to the location of MathJax. ", + "On Linux systems you can also install MathJax using your system package manager.", + call. = FALSE + ) +} diff --git a/man/export.Rd b/man/export.Rd index 5962b3b8ca..f1a0255913 100644 --- a/man/export.Rd +++ b/man/export.Rd @@ -21,7 +21,7 @@ jpeg/png/pdf arguments are passed along to \code{webshot::webshot()}. Otherwise, they are ignored.} } \description{ -Export a plotly graph to a static file +This function is in the process of being deprecated. Use the \code{[orca]()} function instead. } \details{ For SVG plots, a screenshot is taken via \code{webshot::webshot()}. @@ -34,17 +34,6 @@ the RSelenium package is used for exporting WebGL plots. export(plot_ly(economics, x = ~date, y = ~pce)) export(plot_ly(economics, x = ~date, y = ~pce), "plot.pdf") -# svg/webp output or WebGL conversion can be done via RSelenium -if (requireNamespace("RSelenium")) { - rD <- RSelenium::rsDriver(browser = "chrome") - export( - plot_ly(economics, x = ~date, y = ~pce), "plot.svg", rD - ) - export( - plot_ly(economics, x = ~date, y = ~pce, z = ~pop), "yay.svg", rD - ) -} - # If you can't get a selenium server running, another option is to # use Plotly.downloadImage() via htmlwidgets::onRender()... # Downloading images won't work inside RStudio, but you can set the viewer diff --git a/man/orca.Rd b/man/orca.Rd new file mode 100644 index 0000000000..46277f5f37 --- /dev/null +++ b/man/orca.Rd @@ -0,0 +1,53 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/orca.R +\name{orca} +\alias{orca} +\title{Static image export via orca} +\usage{ +orca(p, file = "plot.png", format = tools::file_ext(file), scale = NULL, + width = NULL, height = NULL, mathjax = FALSE, parallel_limit = NULL, + verbose = FALSE, debug = FALSE, safe = FALSE) +} +\arguments{ +\item{p}{a plotly object.} + +\item{file}{output filename.} + +\item{format}{the output format (png, jpeg, webp, svg, pdf, eps).} + +\item{scale}{Sets the image scale. Applies to all output images.} + +\item{width}{Sets the image width. If not set, defaults to \code{layout.width} value. +Applies to all output images.} + +\item{height}{Sets the image height. If not set, defaults to \code{layout.height} value. +Applies to all output images.} + +\item{mathjax}{whether or not to specify a path to mathjax (required to export LaTeX characters). +This should 'just work' in RStudio, but outside RStudio, you may have to set +the PLOTLY_MATHJAX_PATH environment variable to the location of MathJax.} + +\item{parallel_limit}{Sets the limit of parallel tasks run.} + +\item{verbose}{Turn on verbose logging on stdout.} + +\item{debug}{Starts app in debug mode and turn on verbose logs on stdout.} + +\item{safe}{Turns on safe mode: where figures likely to make browser window +hang during image generating are skipped.} +} +\description{ +The function requires the orca command-line utility, +see the installation instructions \href{https://github.com/plotly/orca#installation}{here} +} +\examples{ + +p <- plot_ly(z = ~volcano) \%>\% add_surface() +orca(p, "surface-plot.png") +orca(p, "surface-plot.svg") +orca(p, "surface-plot.pdf") + +} +\author{ +Carson Sievert +} From 1afc1c08f7fecba22760a047dc6418587c570f5a Mon Sep 17 00:00:00 2001 From: Carson Sievert Date: Thu, 31 May 2018 14:17:40 -0500 Subject: [PATCH 2/3] deprecate export(); drop RSelenium from suggests --- DESCRIPTION | 1 - R/export.R | 29 ++++------------------------- man/export.Rd | 24 ++---------------------- 3 files changed, 6 insertions(+), 48 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 4dcae48bc0..964cabb375 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -65,7 +65,6 @@ Suggests: sf, maptools, rgeos, - RSelenium, png, IRdisplay, processx diff --git a/R/export.R b/R/export.R index 397348fd99..91f18d0bbf 100644 --- a/R/export.R +++ b/R/export.R @@ -1,6 +1,6 @@ #' Export a plotly graph to a static file #' -#' This function is in the process of being deprecated. Use the `[orca]()` function instead. +#' This function is in the process of being deprecated (use [orca] instead). #' #' @details For SVG plots, a screenshot is taken via `webshot::webshot()`. #' Since `phantomjs` (and hence `webshot`) does not support WebGL, @@ -11,36 +11,15 @@ #' Valid extensions include 'jpeg' | 'png' | 'webp' | 'svg' | 'pdf' #' @param selenium used only when `p` is a WebGL plot or the output #' format is 'webp' or 'svg'. Should be an object of class "rsClientServer" -#' returned by `RSelenium::rsDriver` (see examples). +#' returned by `RSelenium::rsDriver`. #' @param ... if `p` is non-WebGL and the output file format is #' jpeg/png/pdf arguments are passed along to `webshot::webshot()`. #' Otherwise, they are ignored. #' @export #' @author Carson Sievert -#' @examples -#' # The webshot package handles non-WebGL conversion to jpeg/png/pdf -#' \dontrun{ -#' export(plot_ly(economics, x = ~date, y = ~pce)) -#' export(plot_ly(economics, x = ~date, y = ~pce), "plot.pdf") -#' -#' # If you can't get a selenium server running, another option is to -#' # use Plotly.downloadImage() via htmlwidgets::onRender()... -#' # Downloading images won't work inside RStudio, but you can set the viewer -#' # option to NULL to prompt your default web browser -#' options(viewer = NULL) -#' plot_ly(economics, x = ~date, y = ~pce, z = ~pop) %>% -#' htmlwidgets::onRender( -#' "function(el, x) { -#' var gd = document.getElementById(el.id); -#' Plotly.downloadImage(gd, {format: 'png', width: 600, height: 400, filename: 'plot'}); -#' }" -#' ) -#'} +#' export <- function(p = last_plot(), file = "plotly.png", selenium = NULL, ...) { - message( - "The `export()` function is in the process of being deprecated. ", - "Please use the `orca()` function instead." - ) + .Deprecated("orca") # infer the file type fileType <- tolower(tools::file_ext(file)) diff --git a/man/export.Rd b/man/export.Rd index f1a0255913..b8fb536213 100644 --- a/man/export.Rd +++ b/man/export.Rd @@ -14,40 +14,20 @@ Valid extensions include 'jpeg' | 'png' | 'webp' | 'svg' | 'pdf'} \item{selenium}{used only when \code{p} is a WebGL plot or the output format is 'webp' or 'svg'. Should be an object of class "rsClientServer" -returned by \code{RSelenium::rsDriver} (see examples).} +returned by \code{RSelenium::rsDriver}.} \item{...}{if \code{p} is non-WebGL and the output file format is jpeg/png/pdf arguments are passed along to \code{webshot::webshot()}. Otherwise, they are ignored.} } \description{ -This function is in the process of being deprecated. Use the \code{[orca]()} function instead. +This function is in the process of being deprecated (use \link{orca} instead). } \details{ For SVG plots, a screenshot is taken via \code{webshot::webshot()}. Since \code{phantomjs} (and hence \code{webshot}) does not support WebGL, the RSelenium package is used for exporting WebGL plots. } -\examples{ -# The webshot package handles non-WebGL conversion to jpeg/png/pdf -\dontrun{ -export(plot_ly(economics, x = ~date, y = ~pce)) -export(plot_ly(economics, x = ~date, y = ~pce), "plot.pdf") - -# If you can't get a selenium server running, another option is to -# use Plotly.downloadImage() via htmlwidgets::onRender()... -# Downloading images won't work inside RStudio, but you can set the viewer -# option to NULL to prompt your default web browser -options(viewer = NULL) -plot_ly(economics, x = ~date, y = ~pce, z = ~pop) \%>\% - htmlwidgets::onRender( - "function(el, x) { - var gd = document.getElementById(el.id); - Plotly.downloadImage(gd, {format: 'png', width: 600, height: 400, filename: 'plot'}); - }" - ) -} -} \author{ Carson Sievert } From b922d85680b75afb86d4938ccf8437550d6bffb3 Mon Sep 17 00:00:00 2001 From: Carson Sievert Date: Thu, 31 May 2018 14:20:23 -0500 Subject: [PATCH 3/3] finishing touches --- R/orca.R | 6 ++++-- man/orca.Rd | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/R/orca.R b/R/orca.R index be8f1f5936..104e6aa60c 100644 --- a/R/orca.R +++ b/R/orca.R @@ -1,6 +1,6 @@ #' Static image export via orca #' -#' The function requires the orca command-line utility, +#' The function makes a system call to the orca command-line utility, #' see the installation instructions [here](https://github.com/plotly/orca#installation) #' #' @param p a plotly object. @@ -23,10 +23,12 @@ #' @author Carson Sievert #' @examples #' +#' \dontrun{ #' p <- plot_ly(z = ~volcano) %>% add_surface() #' orca(p, "surface-plot.png") #' orca(p, "surface-plot.svg") #' orca(p, "surface-plot.pdf") +#' } #' orca <- function(p, file = "plot.png", format = tools::file_ext(file), @@ -49,7 +51,7 @@ orca <- function(p, file = "plot.png", format = tools::file_ext(file), plotlyjs_file <- file.path(plotlyjs$src$file, plotlyjs$script) args <- c( - "graph", plotly:::to_JSON(b$x[c("data", "layout")]), + "graph", to_JSON(b$x[c("data", "layout")]), "-o", file, "--format", format, "--plotlyjs", plotlyjs_file, diff --git a/man/orca.Rd b/man/orca.Rd index 46277f5f37..cd7db4948e 100644 --- a/man/orca.Rd +++ b/man/orca.Rd @@ -37,15 +37,17 @@ the PLOTLY_MATHJAX_PATH environment variable to the location of MathJax.} hang during image generating are skipped.} } \description{ -The function requires the orca command-line utility, +The function makes a system call to the orca command-line utility, see the installation instructions \href{https://github.com/plotly/orca#installation}{here} } \examples{ +\dontrun{ p <- plot_ly(z = ~volcano) \%>\% add_surface() orca(p, "surface-plot.png") orca(p, "surface-plot.svg") orca(p, "surface-plot.pdf") +} } \author{