Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

prefer 'agg' for non-interactive R #1556

Merged
merged 3 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# reticulate (development version)

- `reticulate` now prefers using the agg matplotlib backend when the R session
is non-interactive. The backend can also be overridden via the `MPLBACKEND` or
`RETICULATE_MPLBACKEND` environment variables when necessary.

- Fixed issue where callable python objects created with `convert = FALSE` would not be
wrapped in an R function.

Expand Down
52 changes: 43 additions & 9 deletions R/knitr-engine.R
Original file line number Diff line number Diff line change
Expand Up @@ -492,19 +492,53 @@ eng_python_initialize_hooks <- function(options, envir) {

}

eng_python_matplotlib_backend <- function() {

# allow override, just in case
envvars <- c("RETICULATE_MPLBACKEND", "MPLBACKEND")
for (envvar in envvars) {
override <- Sys.getenv(envvar, unset = NA)
if (!is.na(override))
return(override)
}

# if we're currently running testthat tests, force an 'agg' backend
testthat <- Sys.getenv("TESTTHAT", unset = NA)
if (identical(testthat, "true"))
return("agg")

# in RStudio Desktop, enforce a non-Qt matplotlib backend
#
# this is mainly important for older releases of RStudio which were built
# using Qt, since some conda installations might also bundle + use their own
# versions of Qt, and those Qt installations could be incompatible.
#
# newer versions of RStudio set the matplotlib backend to 'agg' more
# explicitly, so this branch could likely be removed in a future reticulate release
if (is_rstudio_desktop())
return("agg")

# prefer using the agg backend in non-interactive environments
# (matplotlib might prefer using the tkAgg backend, but we've seen
# issues when trying to use in some environments, e.g. Windows)
#
# https://github.com/rstudio/rstudio/issues/13840
if (!interactive())
return("agg")

# otherwise, use whatever backend was already configured
""
}

eng_python_initialize_matplotlib <- function(options, envir) {

# early exit if we already initialized
# (this onload hook is registered for multiple matplotlib submodules)
if (identical(.globals$matplotlib_initialized, TRUE))
return(TRUE)

# attempt to enforce a non-Qt matplotlib backend. this is especially important
# with RStudio Desktop as attempting to use a Qt backend will cause issues due
# to mismatched Qt versions between RStudio and Anaconda environments, and
# will cause crashes when attempting to generate plots
testthat <- Sys.getenv("TESTTHAT", unset = NA)
kevinushey marked this conversation as resolved.
Show resolved Hide resolved
if (is_rstudio_desktop() || identical(testthat, "true")) {
backend <- eng_python_matplotlib_backend()
if (nzchar(backend)) {

matplotlib <- import("matplotlib", convert = TRUE)

Expand All @@ -513,13 +547,13 @@ eng_python_initialize_matplotlib <- function(options, envir) {
# specific one when the backend is initialized later
sys <- import("sys", convert = FALSE)
if ("matplotlib.backends" %in% names(sys$modules)) {
matplotlib$pyplot$switch_backend("agg")
matplotlib$pyplot$switch_backend(backend)
} else {
version <- numeric_version(matplotlib$`__version__`)
if (version < "3.3.0")
matplotlib$use("agg", warn = FALSE, force = TRUE)
matplotlib$use(backend, warn = FALSE, force = TRUE)
else
matplotlib$use("agg", force = TRUE)
matplotlib$use(backend, force = TRUE)
}
}

Expand Down