diff --git a/DESCRIPTION b/DESCRIPTION index de7cfc8421..964cabb375 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -65,9 +65,9 @@ Suggests: sf, maptools, 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..91f18d0bbf 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 [orca] 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. @@ -9,43 +11,16 @@ #' 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") -#' -#' # 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 -#' # 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, ...) { + .Deprecated("orca") + # 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..104e6aa60c --- /dev/null +++ b/R/orca.R @@ -0,0 +1,89 @@ +#' Static image export via orca +#' +#' 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. +#' @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 +#' +#' \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), + 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", 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..b8fb536213 100644 --- a/man/export.Rd +++ b/man/export.Rd @@ -14,51 +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{ -Export a plotly graph to a static file +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") - -# 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 -# 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 } diff --git a/man/orca.Rd b/man/orca.Rd new file mode 100644 index 0000000000..cd7db4948e --- /dev/null +++ b/man/orca.Rd @@ -0,0 +1,55 @@ +% 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 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{ +Carson Sievert +}