diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml
index 2b7b21c07e..9130ae3125 100644
--- a/.github/workflows/R-CMD-check.yaml
+++ b/.github/workflows/R-CMD-check.yaml
@@ -72,35 +72,33 @@ jobs:
key: ${{ matrix.config.os }}-${{ steps.install-r.outputs.installed-r-version }}-1-${{ hashFiles('.github/r-depends.rds') }}
restore-keys: ${{ matrix.config.os }}-${{ steps.install-r.outputs.installed-r-version }}-1-
- - name: Install system dependencies
+ - name: Install Linux sysdeps
if: runner.os == 'Linux'
run: |
pak::local_system_requirements(execute = TRUE)
pak::pkg_system_requirements("rcmdcheck", execute = TRUE)
shell: Rscript {0}
-
- - uses: actions/setup-node@v1
- with:
- node-version: ${{ matrix.config.node }}
-
- - name: Install orca
- if: matrix.config.visual_tests == true
- run: npm install -g electron@6.1.4 orca
- shell: bash
-
- - name: Install phantomjs
- if: matrix.config.shinytest == true
- run: |
- pak::pak("shinytest")
- shinytest::installDependencies()
- pak::pak()
- shell: Rscript {0}
-
+
- name: Install dependencies
run: |
- pak::local_install_dev_deps(upgrade = TRUE)
+ if (Sys.info()[['sysname']] == 'Darwin') options(pkgType = 'mac.binary')
+ pak::local_install_dev_deps(upgrade = FALSE)
pak::pkg_install("rcmdcheck")
shell: Rscript {0}
+
+ - name: Set up Python 3.8
+ uses: actions/setup-python@v2
+ with:
+ python-version: 3.8
+
+ - name: Install kaleido
+ if: matrix.config.visual_tests == true
+ run: |
+ sudo chown -R $UID $CONDA # https://github.com/nextstrain/conda/issues/5
+ Rscript -e "reticulate::install_miniconda()"
+ Rscript -e "reticulate::conda_install('r-reticulate', 'python-kaleido')"
+ Rscript -e "reticulate::conda_install('r-reticulate', 'plotly', channel = 'plotly')"
+ Rscript -e "reticulate::use_miniconda('r-reticulate')"
- name: Session info
run: |
@@ -109,10 +107,17 @@ jobs:
sessioninfo::session_info(pkgs, include_base = TRUE)
shell: Rscript {0}
+ - name: Install shinytest deps
+ if: matrix.config.shinytest == true
+ run: |
+ Rscript -e 'shinytest::installDependencies()'
+ R CMD install .
+ shell: bash
+
# Run test() before R CMD check since, for some reason, rcmdcheck::rcmdcheck() skips vdiffr tests
- name: Run Tests
run: |
- options(crayon.enabled = TRUE)
+ options(crayon.enabled = TRUE, testthat.progress.max_fails=1000)
if (!require(devtools)) pak::pak("devtools")
if (!require(reshape2)) pak::pak("reshape2")
res <- devtools::test()
diff --git a/DESCRIPTION b/DESCRIPTION
index a44b1740ad..2ece4f7c43 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -67,13 +67,15 @@ Suggests:
dendextend,
maptools,
rgeos,
+ sf,
png,
IRdisplay,
processx,
plotlyGeoAssets,
forcats,
palmerpenguins,
- rversions
+ rversions,
+ reticulate
LazyData: true
RoxygenNote: 7.1.1
Encoding: UTF-8
diff --git a/NAMESPACE b/NAMESPACE
index 0411fd601d..381958839d 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -34,6 +34,7 @@ S3method(print,api)
S3method(print,api_grid)
S3method(print,api_grid_local)
S3method(print,api_plot)
+S3method(print,kaleidoScope)
S3method(print,plotly_data)
S3method(to_basic,GeomAbline)
S3method(to_basic,GeomAnnotationMap)
@@ -136,6 +137,7 @@ export(hide_guides)
export(hide_legend)
export(highlight)
export(highlight_key)
+export(kaleido)
export(knit_print.api_grid)
export(knit_print.api_grid_local)
export(knit_print.api_plot)
@@ -260,6 +262,7 @@ importFrom(tidyr,unnest)
importFrom(tools,file_ext)
importFrom(tools,file_path_sans_ext)
importFrom(utils,browseURL)
+importFrom(utils,capture.output)
importFrom(utils,data)
importFrom(utils,file.edit)
importFrom(utils,getFromNamespace)
diff --git a/NEWS.md b/NEWS.md
index 0d8ed408a7..619b797338 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -8,6 +8,10 @@
* `ggplotly()` now uses the `layout.legend.title` (instead of `layout.annotations`) plotly.js API to convert guides for discrete scales. (#1961)
+## New Features
+
+* Added new `kaleido()` function for static image exporting via the [kaleido python package](https://github.com/plotly/Kaleido). See `help(kaleido, package = "plotly")` for installation info and example usage. (#1971)
+
## Improvements
* `ggplotly()` now better positions axis titles for `facet_wrap()`/`facet_grid()`. (#1975)
diff --git a/R/kaleido.R b/R/kaleido.R
new file mode 100644
index 0000000000..5ac8127cb4
--- /dev/null
+++ b/R/kaleido.R
@@ -0,0 +1,132 @@
+#' Static image exporting via kaleido
+#'
+#' Static image exporting via [the kaleido python
+#' package](https://github.com/plotly/Kaleido/). `kaleido()` imports
+#' kaleido into a \pkg{reticulate}d Python session and returns a `$transform()`
+#' method for converting R plots into static images (see examples below).
+#'
+#' @section Installation:
+#'
+#' `kaleido()` requires [the kaleido python
+#' package](https://github.com/plotly/Kaleido/) to be usable via the \pkg{reticulate} package. Here is a recommended way to do the installation:
+#'
+#' ```
+#' install.packages('reticulate')
+#' reticulate::install_miniconda()
+#' reticulate::conda_install('r-reticulate', 'python-kaleido')
+#' reticulate::conda_install('r-reticulate', 'plotly', channel = 'plotly')
+#' reticulate::use_miniconda('r-reticulate')
+#' ```
+#'
+#' @param ... not currently used.
+#' @export
+#' @return an environment which contains:
+#' * `transform()`: a function to convert plots objects into static images,
+#' with the following arguments:
+#' * `p`: a plot object.
+#' * `file`: a file path with a suitable file extension (png, jpg, jpeg,
+#' webp, svg, or pdf).
+#' * `width`, `height`: The width/height of the exported image in layout
+#' pixels. If `scale` is 1, this will also be the width/height of the
+#' exported image in physical pixels.
+#' * `scale`: The scale factor to use when exporting the figure. A scale
+#' factor larger than 1.0 will increase the image resolution with
+#' respect to the figure's layout pixel dimensions. Whereas as
+#' scale factor of less than 1.0 will decrease the image resolution.
+#' * `shutdown()`: a function for shutting down any currently running subprocesses
+#' that were launched via `transform()`
+#' * `scope`: a reference to the underlying `kaleido.scopes.plotly.PlotlyScope`
+#' python object. Modify this object to customize the underlying Chromium
+#' subprocess and/or configure other details such as URL to plotly.js, MathJax, etc.
+#' @examples
+#'
+#' \dontrun{
+#' scope <- kaleido()
+#' tmp <- tempfile(fileext = ".png")
+#' scope$transform(plot_ly(x = 1:10), tmp)
+#' file.show(tmp)
+#' # Remove and garbage collect to remove
+#' # R/Python objects and shutdown subprocesses
+#' rm(scope); gc()
+#' }
+#'
+kaleido <- function(...) {
+ if (!rlang::is_installed("reticulate")) {
+ stop("`kaleido()` requires the reticulate package.")
+ }
+ if (!reticulate::py_available(initialize = TRUE)) {
+ stop("`kaleido()` requires `reticulate::py_available()` to be `TRUE`. Do you need to install python?")
+ }
+
+ py <- reticulate::py
+ scope_name <- paste0("scope_", new_id())
+ py[[scope_name]] <- reticulate::import("kaleido")$scopes$plotly$PlotlyScope(
+ plotlyjs = plotlyMainBundlePath()
+ )
+
+ scope <- py[[scope_name]]
+
+ mapbox <- Sys.getenv("MAPBOX_TOKEN", NA)
+ if (!is.na(mapbox)) {
+ scope$mapbox_access_token <- mapbox
+ }
+
+ res <- list2env(list(
+ scope = scope,
+ # https://github.com/plotly/Kaleido/blob/6a46ecae/repos/kaleido/py/kaleido/scopes/plotly.py#L78-L106
+ transform = function(p, file = "figure.png", width = NULL, height = NULL, scale = NULL) {
+ # Perform JSON conversion exactly how the R package would do it
+ # (this is essentially plotly_json(), without the additional unneeded info)
+ # and attach as an attribute on the python scope object
+ scope[["_last_plot"]] <- to_JSON(
+ plotly_build(p)$x[c("data", "layout", "config")]
+ )
+ # On the python side, _last_plot is a string, so use json.loads() to
+ # convert to dict(). This should be fine since json is a dependency of the
+ # BaseScope() https://github.com/plotly/Kaleido/blob/586be5/repos/kaleido/py/kaleido/scopes/base.py#L2
+ transform_cmd <- sprintf(
+ "%s.transform(sys.modules['json'].loads(%s._last_plot), format='%s', width=%s, height=%s, scale=%s)",
+ scope_name, scope_name, tools::file_ext(file),
+ reticulate::r_to_py(width), reticulate::r_to_py(height),
+ reticulate::r_to_py(scale)
+ )
+ # Write the base64 encoded string that transform() returns to disk
+ # https://github.com/plotly/Kaleido/blame/master/README.md#L52
+ reticulate::py_run_string(
+ sprintf("open('%s', 'wb').write(%s)", file, transform_cmd)
+ )
+ },
+ # Shutdown the kaleido subprocesses
+ # https://github.com/plotly/Kaleido/blob/586be5c/repos/kaleido/py/kaleido/scopes/base.py#L71-L72
+ shutdown = function() {
+ reticulate::py_run_string(paste0(scope_name, ".__del__()"))
+ }
+ ))
+
+ # Shutdown subprocesses and delete python scope when
+ # this object is garbage collected by R
+ reg.finalizer(res, onexit = TRUE, function(x) {
+ x$shutdown()
+ reticulate::py_run_string(paste("del", scope_name))
+ })
+
+ class(res) <- "kaleidoScope"
+ res
+}
+
+
+#' Print method for kaleido
+#'
+#' S3 method for [kaleido()].
+#'
+#' @param x a [kaleido()] object.
+#' @param ... currently unused.
+#' @export
+#' @importFrom utils capture.output
+#' @keywords internal
+print.kaleidoScope <- function(x, ...) {
+ args <- formals(x$transform)
+ cat("$transform: function(", paste(names(args), collapse = ", "), ")\n", sep = "")
+ cat("$shutdown: function()\n")
+ cat("$scope: ", utils::capture.output(x$scope))
+}
diff --git a/R/orca.R b/R/orca.R
index 1a394788e4..a5566beb47 100644
--- a/R/orca.R
+++ b/R/orca.R
@@ -1,13 +1,6 @@
-#' Static image exporting
+#' Static image exporting via orca
#'
-#' Export plotly objects to static images (e.g., pdf, png, jpeg, svg, etc) via the
-#' [orca command-line utility](https://github.com/plotly/orca#installation).
-#'
-#' The `orca()` function is designed for exporting one plotly graph whereas `orca_serve()`
-#' is meant for exporting many graphs at once. The former starts and stops an external (nodejs)
-#' process everytime it is called whereas the latter starts up a process when called, then
-#' returns an `export()` method for exporting graphs as well as a `close()` method for stopping
-#' the external (background) process.
+#' Superseded by [kaleido()].
#'
#' @param p a plotly object.
#' @param file output filename.
@@ -67,17 +60,14 @@ orca <- function(p, file = "plot.png", format = tools::file_ext(file),
parallel_limit = NULL, verbose = FALSE, debug = FALSE,
safe = FALSE, more_args = NULL, ...) {
+ .Deprecated("kaleido")
+
orca_available()
b <- plotly_build(p)
# find the relevant plotly.js bundle
- plotlyjs <- plotlyjsBundle(b)
- plotlyjs_path <- file.path(plotlyjs$src$file, plotlyjs$script)
- # package field means src file path should be relative to pkg dir
- if (!is.null(plotlyjs$package)) {
- plotlyjs_path <- system.file(plotlyjs_path, package = plotlyjs$package)
- }
+ plotlyjs_path <- plotlyMainBundlePath()
tmp <- tempfile(fileext = ".json")
cat(to_JSON(b$x[c("data", "layout")]), file = tmp)
@@ -141,17 +131,14 @@ orca_serve <- function(port = 5151, mathjax = FALSE, safe = FALSE, request_limit
keep_alive = TRUE, window_max_number = NULL, quiet = FALSE,
debug = FALSE, more_args = NULL, ...) {
+ .Deprecated("kaleido")
+
# make sure we have the required infrastructure
orca_available()
try_library("processx", "orca_serve")
# use main bundle since any plot can be thrown at the server
- plotlyjs <- plotlyMainBundle()
- plotlyjs_path <- file.path(plotlyjs$src$file, plotlyjs$script)
- # package field means src file path should be relative to pkg dir
- if (!is.null(plotlyjs$package)) {
- plotlyjs_path <- system.file(plotlyjs_path, package = plotlyjs$package)
- }
+ plotlyjs_path <- plotlyMainBundlePath()
args <- c(
"serve",
diff --git a/R/plotly.R b/R/plotly.R
index 5cfa90d8e3..e350e578bf 100644
--- a/R/plotly.R
+++ b/R/plotly.R
@@ -487,6 +487,15 @@ plotlyMainBundle <- function() {
)
}
+plotlyMainBundlePath <- function() {
+ dep <- plotlyMainBundle()
+ path <- file.path(dep$src$file, dep$script)
+ if (!is.null(dep$package)) {
+ path <- system.file(path, package = dep$package)
+ }
+ path
+}
+
plotlyHtmlwidgetsCSS <- function() {
htmltools::htmlDependency(
name = "plotly-htmlwidgets-css",
diff --git a/man/kaleido.Rd b/man/kaleido.Rd
new file mode 100644
index 0000000000..40f733ec18
--- /dev/null
+++ b/man/kaleido.Rd
@@ -0,0 +1,64 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/kaleido.R
+\name{kaleido}
+\alias{kaleido}
+\title{Static image exporting via kaleido}
+\usage{
+kaleido(...)
+}
+\arguments{
+\item{...}{not currently used.}
+}
+\value{
+an environment which contains:
+\itemize{
+\item \code{transform()}: a function to convert plots objects into static images,
+with the following arguments:
+\itemize{
+\item \code{p}: a plot object.
+\item \code{file}: a file path with a suitable file extension (png, jpg, jpeg,
+webp, svg, or pdf).
+\item \code{width}, \code{height}: The width/height of the exported image in layout
+pixels. If \code{scale} is 1, this will also be the width/height of the
+exported image in physical pixels.
+\item \code{scale}: The scale factor to use when exporting the figure. A scale
+factor larger than 1.0 will increase the image resolution with
+respect to the figure's layout pixel dimensions. Whereas as
+scale factor of less than 1.0 will decrease the image resolution.
+}
+\item \code{shutdown()}: a function for shutting down any currently running subprocesses
+that were launched via \code{transform()}
+\item \code{scope}: a reference to the underlying \code{kaleido.scopes.plotly.PlotlyScope}
+python object. Modify this object to customize the underlying Chromium
+subprocess and/or configure other details such as URL to plotly.js, MathJax, etc.
+}
+}
+\description{
+Static image exporting via \href{https://github.com/plotly/Kaleido/}{the kaleido python package}. \code{kaleido()} imports
+kaleido into a \pkg{reticulate}d Python session and returns a \verb{$transform()}
+method for converting R plots into static images (see examples below).
+}
+\section{Installation}{
+
+
+\code{kaleido()} requires \href{https://github.com/plotly/Kaleido/}{the kaleido python package} to be usable via the \pkg{reticulate} package. Here is a recommended way to do the installation:\preformatted{install.packages('reticulate')
+reticulate::install_miniconda()
+reticulate::conda_install('r-reticulate', 'python-kaleido')
+reticulate::conda_install('r-reticulate', 'plotly', channel = 'plotly')
+reticulate::use_miniconda('r-reticulate')
+}
+}
+
+\examples{
+
+\dontrun{
+ scope <- kaleido()
+ tmp <- tempfile(fileext = ".png")
+ scope$transform(plot_ly(x = 1:10), tmp)
+ file.show(tmp)
+ # Remove and garbage collect to remove
+ # R/Python objects and shutdown subprocesses
+ rm(scope); gc()
+}
+
+}
diff --git a/man/orca.Rd b/man/orca.Rd
index d13fc0ad28..ccfcd1c86c 100644
--- a/man/orca.Rd
+++ b/man/orca.Rd
@@ -3,7 +3,7 @@
\name{orca}
\alias{orca}
\alias{orca_serve}
-\title{Static image exporting}
+\title{Static image exporting via orca}
\usage{
orca(
p,
@@ -80,15 +80,7 @@ for specifying display and/or electron options, such as \code{--enable-webgl} or
\item{quiet}{Suppress all logging info.}
}
\description{
-Export plotly objects to static images (e.g., pdf, png, jpeg, svg, etc) via the
-\href{https://github.com/plotly/orca#installation}{orca command-line utility}.
-}
-\details{
-The \code{orca()} function is designed for exporting one plotly graph whereas \code{orca_serve()}
-is meant for exporting many graphs at once. The former starts and stops an external (nodejs)
-process everytime it is called whereas the latter starts up a process when called, then
-returns an \code{export()} method for exporting graphs as well as a \code{close()} method for stopping
-the external (background) process.
+Superseded by \code{\link[=kaleido]{kaleido()}}.
}
\section{Methods}{
diff --git a/man/print.kaleidoScope.Rd b/man/print.kaleidoScope.Rd
new file mode 100644
index 0000000000..a1020407a0
--- /dev/null
+++ b/man/print.kaleidoScope.Rd
@@ -0,0 +1,17 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/kaleido.R
+\name{print.kaleidoScope}
+\alias{print.kaleidoScope}
+\title{Print method for kaleido}
+\usage{
+\method{print}{kaleidoScope}(x, ...)
+}
+\arguments{
+\item{x}{a \code{\link[=kaleido]{kaleido()}} object.}
+
+\item{...}{currently unused.}
+}
+\description{
+S3 method for \code{\link[=kaleido]{kaleido()}}.
+}
+\keyword{internal}
diff --git a/tests/testthat/_snaps/cookbook-lines/cookbook-axes-bar-dodge-color.svg b/tests/testthat/_snaps/cookbook-lines/cookbook-axes-bar-dodge-color.svg
index 22d3096a45..422ca99fed 100644
--- a/tests/testthat/_snaps/cookbook-lines/cookbook-axes-bar-dodge-color.svg
+++ b/tests/testthat/_snaps/cookbook-lines/cookbook-axes-bar-dodge-color.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/cookbook-lines/cookbook-axes-scatter-basic.svg b/tests/testthat/_snaps/cookbook-lines/cookbook-axes-scatter-basic.svg
index 8459e2035c..3768a1b627 100644
--- a/tests/testthat/_snaps/cookbook-lines/cookbook-axes-scatter-basic.svg
+++ b/tests/testthat/_snaps/cookbook-lines/cookbook-axes-scatter-basic.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-area/area-traces-order.svg b/tests/testthat/_snaps/ggplot-area/area-traces-order.svg
index 0434a9975b..bba3a58958 100644
--- a/tests/testthat/_snaps/ggplot-area/area-traces-order.svg
+++ b/tests/testthat/_snaps/ggplot-area/area-traces-order.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-bar/bar-color.svg b/tests/testthat/_snaps/ggplot-bar/bar-color.svg
index 96854bec9a..28a4345257 100644
--- a/tests/testthat/_snaps/ggplot-bar/bar-color.svg
+++ b/tests/testthat/_snaps/ggplot-bar/bar-color.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-bar/bar-dodge.svg b/tests/testthat/_snaps/ggplot-bar/bar-dodge.svg
index de2a5978e5..93789e3da1 100644
--- a/tests/testthat/_snaps/ggplot-bar/bar-dodge.svg
+++ b/tests/testthat/_snaps/ggplot-bar/bar-dodge.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-bar/bar-position-stack.svg b/tests/testthat/_snaps/ggplot-bar/bar-position-stack.svg
index a0f7f1b2ef..cb49b58015 100644
--- a/tests/testthat/_snaps/ggplot-bar/bar-position-stack.svg
+++ b/tests/testthat/_snaps/ggplot-bar/bar-position-stack.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-boxplot/boxplot-fillcolor.svg b/tests/testthat/_snaps/ggplot-boxplot/boxplot-fillcolor.svg
index b07d56e6fc..4a3ca245ee 100644
--- a/tests/testthat/_snaps/ggplot-boxplot/boxplot-fillcolor.svg
+++ b/tests/testthat/_snaps/ggplot-boxplot/boxplot-fillcolor.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-col/col.svg b/tests/testthat/_snaps/ggplot-col/col.svg
index 366e7fcd5a..01847e0545 100644
--- a/tests/testthat/_snaps/ggplot-col/col.svg
+++ b/tests/testthat/_snaps/ggplot-col/col.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-date/date-strings.svg b/tests/testthat/_snaps/ggplot-date/date-strings.svg
index 41aee002f8..e9d737ffdb 100644
--- a/tests/testthat/_snaps/ggplot-date/date-strings.svg
+++ b/tests/testthat/_snaps/ggplot-date/date-strings.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-density/density-fill.svg b/tests/testthat/_snaps/ggplot-density/density-fill.svg
index fe67e4d2f3..f379baeaf3 100644
--- a/tests/testthat/_snaps/ggplot-density/density-fill.svg
+++ b/tests/testthat/_snaps/ggplot-density/density-fill.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-errorbar-horizontal/errorbar-horizontal.svg b/tests/testthat/_snaps/ggplot-errorbar-horizontal/errorbar-horizontal.svg
index fae3fb48da..56d1e0741a 100644
--- a/tests/testthat/_snaps/ggplot-errorbar-horizontal/errorbar-horizontal.svg
+++ b/tests/testthat/_snaps/ggplot-errorbar-horizontal/errorbar-horizontal.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-errorbar/errorbar-unique-groups.svg b/tests/testthat/_snaps/ggplot-errorbar/errorbar-unique-groups.svg
index 06f75170a1..cdbf648722 100644
--- a/tests/testthat/_snaps/ggplot-errorbar/errorbar-unique-groups.svg
+++ b/tests/testthat/_snaps/ggplot-errorbar/errorbar-unique-groups.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-facets/3-panels.svg b/tests/testthat/_snaps/ggplot-facets/3-panels.svg
index 641300c8cb..348e943a8c 100644
--- a/tests/testthat/_snaps/ggplot-facets/3-panels.svg
+++ b/tests/testthat/_snaps/ggplot-facets/3-panels.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-facets/barley.svg b/tests/testthat/_snaps/ggplot-facets/barley.svg
index 145e0fab63..158b85e640 100644
--- a/tests/testthat/_snaps/ggplot-facets/barley.svg
+++ b/tests/testthat/_snaps/ggplot-facets/barley.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-facets/facet-grid-free-x.svg b/tests/testthat/_snaps/ggplot-facets/facet-grid-free-x.svg
index 7eace54ee1..fc7d74af40 100644
--- a/tests/testthat/_snaps/ggplot-facets/facet-grid-free-x.svg
+++ b/tests/testthat/_snaps/ggplot-facets/facet-grid-free-x.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-facets/facet-grid-free.svg b/tests/testthat/_snaps/ggplot-facets/facet-grid-free.svg
index f27841664e..f3a51db618 100644
--- a/tests/testthat/_snaps/ggplot-facets/facet-grid-free.svg
+++ b/tests/testthat/_snaps/ggplot-facets/facet-grid-free.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-facets/facet-grid-labeller.svg b/tests/testthat/_snaps/ggplot-facets/facet-grid-labeller.svg
index 914c9638aa..62f258f0da 100644
--- a/tests/testthat/_snaps/ggplot-facets/facet-grid-labeller.svg
+++ b/tests/testthat/_snaps/ggplot-facets/facet-grid-labeller.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-facets/facet-wrap-free-mult.svg b/tests/testthat/_snaps/ggplot-facets/facet-wrap-free-mult.svg
index 02df0765ca..230fc69b70 100644
--- a/tests/testthat/_snaps/ggplot-facets/facet-wrap-free-mult.svg
+++ b/tests/testthat/_snaps/ggplot-facets/facet-wrap-free-mult.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-facets/facet-wrap-free-y-2.svg b/tests/testthat/_snaps/ggplot-facets/facet-wrap-free-y-2.svg
index db79a82294..91add35b11 100644
--- a/tests/testthat/_snaps/ggplot-facets/facet-wrap-free-y-2.svg
+++ b/tests/testthat/_snaps/ggplot-facets/facet-wrap-free-y-2.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-facets/facet-wrap-free.svg b/tests/testthat/_snaps/ggplot-facets/facet-wrap-free.svg
index 0e3af757f7..f9d5253d1e 100644
--- a/tests/testthat/_snaps/ggplot-facets/facet-wrap-free.svg
+++ b/tests/testthat/_snaps/ggplot-facets/facet-wrap-free.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-facets/facet-wrap-labeller.svg b/tests/testthat/_snaps/ggplot-facets/facet-wrap-labeller.svg
index 55bca192bf..3b0802bb2c 100644
--- a/tests/testthat/_snaps/ggplot-facets/facet-wrap-labeller.svg
+++ b/tests/testthat/_snaps/ggplot-facets/facet-wrap-labeller.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-facets/facet-wrap.svg b/tests/testthat/_snaps/ggplot-facets/facet-wrap.svg
index 038084b2ba..cdac041803 100644
--- a/tests/testthat/_snaps/ggplot-facets/facet-wrap.svg
+++ b/tests/testthat/_snaps/ggplot-facets/facet-wrap.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-heatmap/heatmap-discrete.svg b/tests/testthat/_snaps/ggplot-heatmap/heatmap-discrete.svg
index d23c0fd06a..9c462f95b0 100644
--- a/tests/testthat/_snaps/ggplot-heatmap/heatmap-discrete.svg
+++ b/tests/testthat/_snaps/ggplot-heatmap/heatmap-discrete.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-heatmap/heatmap-midpoint.svg b/tests/testthat/_snaps/ggplot-heatmap/heatmap-midpoint.svg
index f285f0a90e..4260614d0d 100644
--- a/tests/testthat/_snaps/ggplot-heatmap/heatmap-midpoint.svg
+++ b/tests/testthat/_snaps/ggplot-heatmap/heatmap-midpoint.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-heatmap/heatmap.svg b/tests/testthat/_snaps/ggplot-heatmap/heatmap.svg
index b8a0a8f25b..33fe075d00 100644
--- a/tests/testthat/_snaps/ggplot-heatmap/heatmap.svg
+++ b/tests/testthat/_snaps/ggplot-heatmap/heatmap.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-hex/hex-basic.svg b/tests/testthat/_snaps/ggplot-hex/hex-basic.svg
index 0d70ba37fc..9277790281 100644
--- a/tests/testthat/_snaps/ggplot-hex/hex-basic.svg
+++ b/tests/testthat/_snaps/ggplot-hex/hex-basic.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-hex/hex-bins.svg b/tests/testthat/_snaps/ggplot-hex/hex-bins.svg
index 0df88b6b1f..6c32c75085 100644
--- a/tests/testthat/_snaps/ggplot-hex/hex-bins.svg
+++ b/tests/testthat/_snaps/ggplot-hex/hex-bins.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-hex/hex-binwidth.svg b/tests/testthat/_snaps/ggplot-hex/hex-binwidth.svg
index 9e1432b287..404b84fb73 100644
--- a/tests/testthat/_snaps/ggplot-hex/hex-binwidth.svg
+++ b/tests/testthat/_snaps/ggplot-hex/hex-binwidth.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-histogram/histogram-fill-factor-facets.svg b/tests/testthat/_snaps/ggplot-histogram/histogram-fill-factor-facets.svg
index 9bf236a9eb..96a5a2f728 100644
--- a/tests/testthat/_snaps/ggplot-histogram/histogram-fill-factor-facets.svg
+++ b/tests/testthat/_snaps/ggplot-histogram/histogram-fill-factor-facets.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-histogram/histogram-fill.svg b/tests/testthat/_snaps/ggplot-histogram/histogram-fill.svg
index 58a328f225..36b168ef5d 100644
--- a/tests/testthat/_snaps/ggplot-histogram/histogram-fill.svg
+++ b/tests/testthat/_snaps/ggplot-histogram/histogram-fill.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-labels/labs-element-blank.svg b/tests/testthat/_snaps/ggplot-labels/labs-element-blank.svg
index 18b5187b96..d787c370f4 100644
--- a/tests/testthat/_snaps/ggplot-labels/labs-element-blank.svg
+++ b/tests/testthat/_snaps/ggplot-labels/labs-element-blank.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-legend/legend-many-legend-items.svg b/tests/testthat/_snaps/ggplot-legend/legend-many-legend-items.svg
index dc91cf1222..e352d3cdcd 100644
--- a/tests/testthat/_snaps/ggplot-legend/legend-many-legend-items.svg
+++ b/tests/testthat/_snaps/ggplot-legend/legend-many-legend-items.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-legend/legend-one-entry.svg b/tests/testthat/_snaps/ggplot-legend/legend-one-entry.svg
index cd262fc7b4..3a476bfdf0 100644
--- a/tests/testthat/_snaps/ggplot-legend/legend-one-entry.svg
+++ b/tests/testthat/_snaps/ggplot-legend/legend-one-entry.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-legend/legend-very-long-legend-items.svg b/tests/testthat/_snaps/ggplot-legend/legend-very-long-legend-items.svg
index 89e9253a37..fb46854158 100644
--- a/tests/testthat/_snaps/ggplot-legend/legend-very-long-legend-items.svg
+++ b/tests/testthat/_snaps/ggplot-legend/legend-very-long-legend-items.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-legend/scatter-legend.svg b/tests/testthat/_snaps/ggplot-legend/scatter-legend.svg
index 840e4a4f99..255b20caee 100644
--- a/tests/testthat/_snaps/ggplot-legend/scatter-legend.svg
+++ b/tests/testthat/_snaps/ggplot-legend/scatter-legend.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-lines/linetype-colors.svg b/tests/testthat/_snaps/ggplot-lines/linetype-colors.svg
index 9becfb618a..efa8b91cd9 100644
--- a/tests/testthat/_snaps/ggplot-lines/linetype-colors.svg
+++ b/tests/testthat/_snaps/ggplot-lines/linetype-colors.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-lines/linetype-types.svg b/tests/testthat/_snaps/ggplot-lines/linetype-types.svg
index cc6eb1ebf0..8a6e044af8 100644
--- a/tests/testthat/_snaps/ggplot-lines/linetype-types.svg
+++ b/tests/testthat/_snaps/ggplot-lines/linetype-types.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-map/map-facet.svg b/tests/testthat/_snaps/ggplot-map/map-facet.svg
index a88d89dbb5..95e8a8e456 100644
--- a/tests/testthat/_snaps/ggplot-map/map-facet.svg
+++ b/tests/testthat/_snaps/ggplot-map/map-facet.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-path/path-colored-groups-stay-together.svg b/tests/testthat/_snaps/ggplot-path/path-colored-groups-stay-together.svg
index 50252de33a..05e2079a27 100644
--- a/tests/testthat/_snaps/ggplot-path/path-colored-groups-stay-together.svg
+++ b/tests/testthat/_snaps/ggplot-path/path-colored-groups-stay-together.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-path/path-colors.svg b/tests/testthat/_snaps/ggplot-path/path-colors.svg
index 60061c6e98..0a2ab21493 100644
--- a/tests/testthat/_snaps/ggplot-path/path-colors.svg
+++ b/tests/testthat/_snaps/ggplot-path/path-colors.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-path/path-colors2.svg b/tests/testthat/_snaps/ggplot-path/path-colors2.svg
index b3915b58c2..003f85a6be 100644
--- a/tests/testthat/_snaps/ggplot-path/path-colors2.svg
+++ b/tests/testthat/_snaps/ggplot-path/path-colors2.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-path/path-line-symbols.svg b/tests/testthat/_snaps/ggplot-path/path-line-symbols.svg
index 72ba94b8cb..2064c6b6cd 100644
--- a/tests/testthat/_snaps/ggplot-path/path-line-symbols.svg
+++ b/tests/testthat/_snaps/ggplot-path/path-line-symbols.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-point/all-shapes.svg b/tests/testthat/_snaps/ggplot-point/all-shapes.svg
index 52de0c694d..8a3abdcb25 100644
--- a/tests/testthat/_snaps/ggplot-point/all-shapes.svg
+++ b/tests/testthat/_snaps/ggplot-point/all-shapes.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-polygons/polygon-aes-color.svg b/tests/testthat/_snaps/ggplot-polygons/polygon-aes-color.svg
index de9910fb8d..15ab74742e 100644
--- a/tests/testthat/_snaps/ggplot-polygons/polygon-aes-color.svg
+++ b/tests/testthat/_snaps/ggplot-polygons/polygon-aes-color.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-rect/rect-color.svg b/tests/testthat/_snaps/ggplot-rect/rect-color.svg
index bfd09d4027..dadd68be4d 100644
--- a/tests/testthat/_snaps/ggplot-rect/rect-color.svg
+++ b/tests/testthat/_snaps/ggplot-rect/rect-color.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-ribbon/ribbon-colour.svg b/tests/testthat/_snaps/ggplot-ribbon/ribbon-colour.svg
index 263e5feea0..3e5f1e8823 100644
--- a/tests/testthat/_snaps/ggplot-ribbon/ribbon-colour.svg
+++ b/tests/testthat/_snaps/ggplot-ribbon/ribbon-colour.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-segment/segment-multiple-non-numeric.svg b/tests/testthat/_snaps/ggplot-segment/segment-multiple-non-numeric.svg
index 0cf0830070..e87801858c 100644
--- a/tests/testthat/_snaps/ggplot-segment/segment-multiple-non-numeric.svg
+++ b/tests/testthat/_snaps/ggplot-segment/segment-multiple-non-numeric.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-sf/sf-fill-text.svg b/tests/testthat/_snaps/ggplot-sf/sf-fill-text.svg
index 3b69f6c9f7..7fd6eb8fce 100644
--- a/tests/testthat/_snaps/ggplot-sf/sf-fill-text.svg
+++ b/tests/testthat/_snaps/ggplot-sf/sf-fill-text.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-size/size-global-scaling.svg b/tests/testthat/_snaps/ggplot-size/size-global-scaling.svg
index 37f34b2d06..b903812934 100644
--- a/tests/testthat/_snaps/ggplot-size/size-global-scaling.svg
+++ b/tests/testthat/_snaps/ggplot-size/size-global-scaling.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-smooth/smooth-facet.svg b/tests/testthat/_snaps/ggplot-smooth/smooth-facet.svg
index 6b9d354bdb..53d2a52291 100644
--- a/tests/testthat/_snaps/ggplot-smooth/smooth-facet.svg
+++ b/tests/testthat/_snaps/ggplot-smooth/smooth-facet.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-step/step-gg-hv.svg b/tests/testthat/_snaps/ggplot-step/step-gg-hv.svg
index c838d11505..881037778c 100644
--- a/tests/testthat/_snaps/ggplot-step/step-gg-hv.svg
+++ b/tests/testthat/_snaps/ggplot-step/step-gg-hv.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-text/text-colour.svg b/tests/testthat/_snaps/ggplot-text/text-colour.svg
index 0c231a0d8a..9704eff777 100644
--- a/tests/testthat/_snaps/ggplot-text/text-colour.svg
+++ b/tests/testthat/_snaps/ggplot-text/text-colour.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-ticks/ticks-boxes-facet-grid.svg b/tests/testthat/_snaps/ggplot-ticks/ticks-boxes-facet-grid.svg
index 05c9fc6417..00e03cb0f7 100644
--- a/tests/testthat/_snaps/ggplot-ticks/ticks-boxes-facet-grid.svg
+++ b/tests/testthat/_snaps/ggplot-ticks/ticks-boxes-facet-grid.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-ticks/ticks-boxes-scales-free.svg b/tests/testthat/_snaps/ggplot-ticks/ticks-boxes-scales-free.svg
index 85d854e17f..c6abb1e335 100644
--- a/tests/testthat/_snaps/ggplot-ticks/ticks-boxes-scales-free.svg
+++ b/tests/testthat/_snaps/ggplot-ticks/ticks-boxes-scales-free.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-ticks/ticks-boxes-space-free.svg b/tests/testthat/_snaps/ggplot-ticks/ticks-boxes-space-free.svg
index 85d854e17f..c6abb1e335 100644
--- a/tests/testthat/_snaps/ggplot-ticks/ticks-boxes-space-free.svg
+++ b/tests/testthat/_snaps/ggplot-ticks/ticks-boxes-space-free.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-ticks/ticks-flip-grid-free.svg b/tests/testthat/_snaps/ggplot-ticks/ticks-flip-grid-free.svg
index 5a5aa3dbd6..9ea33bd957 100644
--- a/tests/testthat/_snaps/ggplot-ticks/ticks-flip-grid-free.svg
+++ b/tests/testthat/_snaps/ggplot-ticks/ticks-flip-grid-free.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-ticks/ticks-flip-grid.svg b/tests/testthat/_snaps/ggplot-ticks/ticks-flip-grid.svg
index 4c48d7fc7d..40aa38b7f5 100644
--- a/tests/testthat/_snaps/ggplot-ticks/ticks-flip-grid.svg
+++ b/tests/testthat/_snaps/ggplot-ticks/ticks-flip-grid.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/ggplot-tooltip/heatmap-discrete-tooltip.svg b/tests/testthat/_snaps/ggplot-tooltip/heatmap-discrete-tooltip.svg
index 19469c5e2b..2b1cd17a00 100644
--- a/tests/testthat/_snaps/ggplot-tooltip/heatmap-discrete-tooltip.svg
+++ b/tests/testthat/_snaps/ggplot-tooltip/heatmap-discrete-tooltip.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/mean-error-bars/error-rect-alpha.svg b/tests/testthat/_snaps/mean-error-bars/error-rect-alpha.svg
index ceefe8ed6f..a5ae73351e 100644
--- a/tests/testthat/_snaps/mean-error-bars/error-rect-alpha.svg
+++ b/tests/testthat/_snaps/mean-error-bars/error-rect-alpha.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-color/plotly-color-bar-color-factor-custom.svg b/tests/testthat/_snaps/plotly-color/plotly-color-bar-color-factor-custom.svg
index 0d55e50c69..7db2e49f2f 100644
--- a/tests/testthat/_snaps/plotly-color/plotly-color-bar-color-factor-custom.svg
+++ b/tests/testthat/_snaps/plotly-color/plotly-color-bar-color-factor-custom.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-color/plotly-color-color-manual.svg b/tests/testthat/_snaps/plotly-color/plotly-color-color-manual.svg
index 0af50a426b..47752d4746 100644
--- a/tests/testthat/_snaps/plotly-color/plotly-color-color-manual.svg
+++ b/tests/testthat/_snaps/plotly-color/plotly-color-color-manual.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-color/plotly-color-scatterplot-color-factor.svg b/tests/testthat/_snaps/plotly-color/plotly-color-scatterplot-color-factor.svg
index 1c237d0e92..4ba7d31f0e 100644
--- a/tests/testthat/_snaps/plotly-color/plotly-color-scatterplot-color-factor.svg
+++ b/tests/testthat/_snaps/plotly-color/plotly-color-scatterplot-color-factor.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-color/plotly-color-scatterplot-color-numeric-custom.svg b/tests/testthat/_snaps/plotly-color/plotly-color-scatterplot-color-numeric-custom.svg
index 854462136a..0ea13134b4 100644
--- a/tests/testthat/_snaps/plotly-color/plotly-color-scatterplot-color-numeric-custom.svg
+++ b/tests/testthat/_snaps/plotly-color/plotly-color-scatterplot-color-numeric-custom.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-color/plotly-color-scatterplot-color-numeric.svg b/tests/testthat/_snaps/plotly-color/plotly-color-scatterplot-color-numeric.svg
index a90227ebfc..55c5f845aa 100644
--- a/tests/testthat/_snaps/plotly-color/plotly-color-scatterplot-color-numeric.svg
+++ b/tests/testthat/_snaps/plotly-color/plotly-color-scatterplot-color-numeric.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-color/plotly-color-scatterplot-scatter3d-axes.svg b/tests/testthat/_snaps/plotly-color/plotly-color-scatterplot-scatter3d-axes.svg
index 3024d18ae5..964a2551d0 100644
--- a/tests/testthat/_snaps/plotly-color/plotly-color-scatterplot-scatter3d-axes.svg
+++ b/tests/testthat/_snaps/plotly-color/plotly-color-scatterplot-scatter3d-axes.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar-expand.svg b/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar-expand.svg
index 1ac30e3341..6891216019 100644
--- a/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar-expand.svg
+++ b/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar-expand.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar-restrict.svg b/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar-restrict.svg
index cd82102cc4..74a1834f69 100644
--- a/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar-restrict.svg
+++ b/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar-restrict.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar-z-expand.svg b/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar-z-expand.svg
index 86738a9778..e8e0a7da30 100644
--- a/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar-z-expand.svg
+++ b/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar-z-expand.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar-z-restrict.svg b/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar-z-restrict.svg
index f61f0c00f2..70ae6d6246 100644
--- a/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar-z-restrict.svg
+++ b/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar-z-restrict.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar.svg b/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar.svg
index 84ae4a1945..e6a1aa3a22 100644
--- a/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar.svg
+++ b/tests/testthat/_snaps/plotly-colorbar/plotly-colorbar.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-colorscale/colorramp.svg b/tests/testthat/_snaps/plotly-colorscale/colorramp.svg
index 8ba1fab29c..11b22714a4 100644
--- a/tests/testthat/_snaps/plotly-colorscale/colorramp.svg
+++ b/tests/testthat/_snaps/plotly-colorscale/colorramp.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-colorscale/contour-alpha.svg b/tests/testthat/_snaps/plotly-colorscale/contour-alpha.svg
index c4fb0f6b63..87fbd024a1 100644
--- a/tests/testthat/_snaps/plotly-colorscale/contour-alpha.svg
+++ b/tests/testthat/_snaps/plotly-colorscale/contour-alpha.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-colorscale/contour-colorscale.svg b/tests/testthat/_snaps/plotly-colorscale/contour-colorscale.svg
index 647258b2a7..943bae3a25 100644
--- a/tests/testthat/_snaps/plotly-colorscale/contour-colorscale.svg
+++ b/tests/testthat/_snaps/plotly-colorscale/contour-colorscale.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-colorscale/marker-colorscale.svg b/tests/testthat/_snaps/plotly-colorscale/marker-colorscale.svg
index a8c2fb0a8e..d5fc23f86b 100644
--- a/tests/testthat/_snaps/plotly-colorscale/marker-colorscale.svg
+++ b/tests/testthat/_snaps/plotly-colorscale/marker-colorscale.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-colorscale/test-df.svg b/tests/testthat/_snaps/plotly-colorscale/test-df.svg
index af30638074..e25107c366 100644
--- a/tests/testthat/_snaps/plotly-colorscale/test-df.svg
+++ b/tests/testthat/_snaps/plotly-colorscale/test-df.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-colorscale/test-list-2.svg b/tests/testthat/_snaps/plotly-colorscale/test-list-2.svg
index 664be27807..2c3249c151 100644
--- a/tests/testthat/_snaps/plotly-colorscale/test-list-2.svg
+++ b/tests/testthat/_snaps/plotly-colorscale/test-list-2.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-colorscale/test-list-3.svg b/tests/testthat/_snaps/plotly-colorscale/test-list-3.svg
index 664be27807..2c3249c151 100644
--- a/tests/testthat/_snaps/plotly-colorscale/test-list-3.svg
+++ b/tests/testthat/_snaps/plotly-colorscale/test-list-3.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-colorscale/test-list.svg b/tests/testthat/_snaps/plotly-colorscale/test-list.svg
index af30638074..e25107c366 100644
--- a/tests/testthat/_snaps/plotly-colorscale/test-list.svg
+++ b/tests/testthat/_snaps/plotly-colorscale/test-list.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-colorscale/test-matrix.svg b/tests/testthat/_snaps/plotly-colorscale/test-matrix.svg
index af30638074..e25107c366 100644
--- a/tests/testthat/_snaps/plotly-colorscale/test-matrix.svg
+++ b/tests/testthat/_snaps/plotly-colorscale/test-matrix.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-group/plotly-nas-within-color.svg b/tests/testthat/_snaps/plotly-group/plotly-nas-within-color.svg
index cd41cdf840..442d6db24b 100644
--- a/tests/testthat/_snaps/plotly-group/plotly-nas-within-color.svg
+++ b/tests/testthat/_snaps/plotly-group/plotly-nas-within-color.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-linetype/plotly-linetype-alphabetical.svg b/tests/testthat/_snaps/plotly-linetype/plotly-linetype-alphabetical.svg
index 621611956d..14789f237c 100644
--- a/tests/testthat/_snaps/plotly-linetype/plotly-linetype-alphabetical.svg
+++ b/tests/testthat/_snaps/plotly-linetype/plotly-linetype-alphabetical.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-linetype/plotly-linetype-linetype.svg b/tests/testthat/_snaps/plotly-linetype/plotly-linetype-linetype.svg
index 8db01b0abb..4969c67973 100644
--- a/tests/testthat/_snaps/plotly-linetype/plotly-linetype-linetype.svg
+++ b/tests/testthat/_snaps/plotly-linetype/plotly-linetype-linetype.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-size/sizemode.svg b/tests/testthat/_snaps/plotly-size/sizemode.svg
index 79808cc224..4feeda5d2f 100644
--- a/tests/testthat/_snaps/plotly-size/sizemode.svg
+++ b/tests/testthat/_snaps/plotly-size/sizemode.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-subplot/plotly-subplot-geo-cartesian.svg b/tests/testthat/_snaps/plotly-subplot/plotly-subplot-geo-cartesian.svg
index 5f17ea4af7..60dbed2a50 100644
--- a/tests/testthat/_snaps/plotly-subplot/plotly-subplot-geo-cartesian.svg
+++ b/tests/testthat/_snaps/plotly-subplot/plotly-subplot-geo-cartesian.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-subplot/plotly-subplot-ggmatrix.svg b/tests/testthat/_snaps/plotly-subplot/plotly-subplot-ggmatrix.svg
index 9d607819ae..91e0858391 100644
--- a/tests/testthat/_snaps/plotly-subplot/plotly-subplot-ggmatrix.svg
+++ b/tests/testthat/_snaps/plotly-subplot/plotly-subplot-ggmatrix.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-subplot/plotly-subplot-shareboth.svg b/tests/testthat/_snaps/plotly-subplot/plotly-subplot-shareboth.svg
index 96e471340a..97cc7c9931 100644
--- a/tests/testthat/_snaps/plotly-subplot/plotly-subplot-shareboth.svg
+++ b/tests/testthat/_snaps/plotly-subplot/plotly-subplot-shareboth.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-subplot/plotly-subplot-simple.svg b/tests/testthat/_snaps/plotly-subplot/plotly-subplot-simple.svg
index e5c90c3a1a..4ed99cb0ea 100644
--- a/tests/testthat/_snaps/plotly-subplot/plotly-subplot-simple.svg
+++ b/tests/testthat/_snaps/plotly-subplot/plotly-subplot-simple.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-subplot/plotly-subplot-subplot-legendgroup.svg b/tests/testthat/_snaps/plotly-subplot/plotly-subplot-subplot-legendgroup.svg
index d460d28c26..770ff1a7e4 100644
--- a/tests/testthat/_snaps/plotly-subplot/plotly-subplot-subplot-legendgroup.svg
+++ b/tests/testthat/_snaps/plotly-subplot/plotly-subplot-subplot-legendgroup.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-subplot/subplot-reposition-annotation.svg b/tests/testthat/_snaps/plotly-subplot/subplot-reposition-annotation.svg
index ee5ead7d9b..3697bf870f 100644
--- a/tests/testthat/_snaps/plotly-subplot/subplot-reposition-annotation.svg
+++ b/tests/testthat/_snaps/plotly-subplot/subplot-reposition-annotation.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly-symbol/plotly-symbol-logical.svg b/tests/testthat/_snaps/plotly-symbol/plotly-symbol-logical.svg
index 461401d867..a8d862f110 100644
--- a/tests/testthat/_snaps/plotly-symbol/plotly-symbol-logical.svg
+++ b/tests/testthat/_snaps/plotly-symbol/plotly-symbol-logical.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly/layout-grid.svg b/tests/testthat/_snaps/plotly/layout-grid.svg
index 3e174605f4..67da328d14 100644
--- a/tests/testthat/_snaps/plotly/layout-grid.svg
+++ b/tests/testthat/_snaps/plotly/layout-grid.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly/plotly-alpha-blending.svg b/tests/testthat/_snaps/plotly/plotly-alpha-blending.svg
index 282bba28b8..dfc59bce2d 100644
--- a/tests/testthat/_snaps/plotly/plotly-alpha-blending.svg
+++ b/tests/testthat/_snaps/plotly/plotly-alpha-blending.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly/plotly-box-data-array.svg b/tests/testthat/_snaps/plotly/plotly-box-data-array.svg
index 1ce66a81fd..7d158da74d 100644
--- a/tests/testthat/_snaps/plotly/plotly-box-data-array.svg
+++ b/tests/testthat/_snaps/plotly/plotly-box-data-array.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly/plotly-character-axis.svg b/tests/testthat/_snaps/plotly/plotly-character-axis.svg
index 879495417b..d6ca87256a 100644
--- a/tests/testthat/_snaps/plotly/plotly-character-axis.svg
+++ b/tests/testthat/_snaps/plotly/plotly-character-axis.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/_snaps/plotly/plotly-time-series-summary.svg b/tests/testthat/_snaps/plotly/plotly-time-series-summary.svg
index a4abc437b6..2d31546eac 100644
--- a/tests/testthat/_snaps/plotly/plotly-time-series-summary.svg
+++ b/tests/testthat/_snaps/plotly/plotly-time-series-summary.svg
@@ -1 +1 @@
-
+
diff --git a/tests/testthat/helper-vdiffr.R b/tests/testthat/helper-vdiffr.R
index 2079e50f5d..b27435a1e8 100644
--- a/tests/testthat/helper-vdiffr.R
+++ b/tests/testthat/helper-vdiffr.R
@@ -3,20 +3,12 @@ visual_testing <- grepl("true", Sys.getenv("VISUAL_TESTS"), fixed = TRUE)
message("Visual testing is ", if (!visual_testing) "not ", "enabled.")
# start up the orca image server
-if (visual_testing) {
- # try 20 random ports
- for (vdiff_port_tries in 1:20) {
- port <- floor(runif(1, 3001, 8000))
- success <- tryFALSE({
- # init image server with webgl enabled
- # maybe someday this won't be necessary
- # https://github.com/plotly/orca/issues/127
- orcaServer <- orca_serve(port = port, more_args = "--enable-webgl")
- orcaServer$process$is_alive() && is.null(orcaServer$process$get_exit_status())
- })
- if (success) break
- }
-}
+imageServer <- if (visual_testing) {
+ kaleido()
+} else {
+ list(transform = function(...) stop("Visual testing is disabled!"))
+}
+
expect_doppelganger <- function(p, name, ...) {
@@ -53,13 +45,9 @@ write_plotly_svg <- function(p, file) {
p$x$data <- Map(function(tr, id) { tr$uid <- id; tr }, p$x$data, uid_data)
# write svg to disk
- # NOTE TO SELF: yes, it would be great to use `orca_serve()` here, but it gives
- # slightly different results from `orca()` (ordering of attributes are different)
- # and `orca_serve()` doesn't seem to run reliably everywhere
owd <- setwd(dirname(file))
on.exit(setwd(owd))
- # NOTE: the dimensions here should match the server args part of xvfb-run
- orcaServer$export(p, file = basename(file), width = 640, height = 480)
+ imageServer$transform(p, file = basename(file), width = 640, height = 480)
# strip out non-deterministic fullLayout.uid
# TODO: if and when plotly provides an API to pre-specify, use it!