Skip to content

Commit a6af69e

Browse files
authored
Merge pull request #1 from ropensci/master
Update to 1.52.2
2 parents c299c5f + 65493ad commit a6af69e

File tree

451 files changed

+1028
-580
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

451 files changed

+1028
-580
lines changed

.travis.yml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,3 @@ before_install:
3434
before_script:
3535
- if [[ "$TRAVIS_R_VERSION_STRING" == "release" ]]; then docker run -e GITHUB_PAT=$GITHUB_PAT -e MAPBOX_TOKEN=$MAPBOX_TOKEN -e VMODE="ci" -v $(pwd):/home/plotly --privileged cpsievert/plotly-orca; fi
3636

37-
# work around temporary travis + R 3.5 bug
38-
r_packages: devtools
39-
40-
# temporary: needed for plotly input testing in shiny
41-
r_github_packages:
42-
- rstudio/shinytest
43-
- r-lib/remotes

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: plotly
22
Title: Create Interactive Web Graphics via 'plotly.js'
3-
Version: 4.9.0.9000
3+
Version: 4.9.1.9000
44
Authors@R: c(person("Carson", "Sievert", role = c("aut", "cre"),
55
email = "cpsievert1@gmail.com", comment = c(ORCID = "0000-0002-4958-2844")),
66
person("Chris", "Parmer", role = "aut",
@@ -72,6 +72,6 @@ Suggests:
7272
plotlyGeoAssets,
7373
forcats
7474
LazyData: true
75-
RoxygenNote: 6.1.1
75+
RoxygenNote: 7.0.2
7676
Encoding: UTF-8
7777
Roxygen: list(markdown = TRUE)

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ export(add_heatmap)
9494
export(add_histogram)
9595
export(add_histogram2d)
9696
export(add_histogram2dcontour)
97+
export(add_image)
9798
export(add_lines)
9899
export(add_markers)
99100
export(add_mesh)

NEWS.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,27 @@
1-
# 4.9.0.9000
1+
# 4.9.1.9000
2+
3+
## Changes to plotly.js
4+
5+
* This version of the R package upgrades the version of the underlying plotly.js library from v1.49.4 to v1.52.2. This includes many bug fixes, improvements, as well as 2 new trace types: `treemap` and `image`. The [plotly.js release page](https://github.com/plotly/plotly.js/releases) has the full list of changes.
6+
7+
## IMPROVEMENTS
8+
9+
* The `add_image()` function was added to make it easier to create image traces via `raster` objects.
10+
11+
## BUG FIXES
12+
13+
* `add_sf()`/`geom_sf()` now correctly handle geometry columns that are named something other than `"geometry"` (#1659).
14+
15+
# 4.9.1
216

317
## Changes to plotly.js
418

519
* This version of the R package upgrades the version of the underlying plotly.js library from v1.46.1 to v1.49.4. The [plotly.js release page](https://github.com/plotly/plotly.js/releases) has the full list of changes.
620

21+
## IMPROVEMENTS
22+
23+
* `event_data()` gains support for the `plotly_sunburstclick` event (#1648)
24+
725
## BUG FIXES
826

927
* Fixed an issue with correctly capturing the return value of user-expressions to `renderPlotly()` (#1528).

R/add.R

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ add_data <- function(p, data = NULL) {
2424
#' @inheritParams plot_ly
2525
#' @param p a plotly object
2626
#' @param inherit inherit attributes from [plot_ly()]?
27-
#' @param z a numeric matrix
27+
#' @param z a numeric matrix (unless [add_image()], which wants a raster object, see [as.raster()]).
2828
#' @param x the x variable.
2929
#' @param y the y variable.
3030
#' @param text textual labels.
@@ -393,6 +393,43 @@ add_ribbons <- function(p, x = NULL, ymin = NULL, ymax = NULL, ...,
393393
)
394394
}
395395

396+
#' @inheritParams add_trace
397+
#' @rdname add_trace
398+
#' @param colormodel Sets the colormodel for image traces if `z` is not a raster object.
399+
#' If `z` is a raster object (see [as.raster()]), the `'rgba'` colormodel is always used.
400+
#' @export
401+
add_image <- function(p, z = NULL, colormodel = NULL, ..., data = NULL, inherit = TRUE) {
402+
403+
if (inherit) {
404+
z <- z %||% p$x$attrs[[1]][["z"]]
405+
colormodel <- colormodel %||% p$x$attrs[[1]][["colormodel"]]
406+
}
407+
408+
if (inherits(z, "raster")) {
409+
cols <- col2rgb(z, alpha = TRUE)
410+
dims <- c(dim(z), 4)
411+
z <- array(numeric(prod(dims)), dims)
412+
matrix_ <- function(x) {
413+
matrix(x, byrow = TRUE, nrow = dims[1], ncol = dims[2])
414+
}
415+
z[,,1] <- matrix_(cols["red",])
416+
z[,,2] <- matrix_(cols["green",])
417+
z[,,3] <- matrix_(cols["blue",])
418+
z[,,4] <- matrix_(cols["alpha",])
419+
420+
# Throw if we detect another colormodel
421+
if (!identical(colormodel %||% "rgba", "rgba")) {
422+
warning("Passing a raster object to z requires rgba colormodel")
423+
}
424+
colormodel <- "rgba"
425+
}
426+
427+
add_trace(
428+
p, z = z, colormodel = colormodel, ...,
429+
data = data, type = "image"
430+
)
431+
}
432+
396433
#' @inheritParams add_trace
397434
#' @rdname add_trace
398435
#' @param r For polar chart only. Sets the radial coordinates.

R/embed.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#' Embed a plot as an iframe into a Jupyter Notebook
22
#' @param x a plotly object
33
#' @param width attribute of the iframe. If `NULL`, the width in
4-
#' `plot_ly` is used. If that is also `NULL`, '100\%' is the default.
4+
#' `plot_ly` is used. If that is also `NULL`, '100%' is the default.
55
#' @param height attribute of the iframe. If `NULL`, the height in
66
#' `plot_ly` is used. If that is also `NULL`, '400px' is the default.
77
#' @param file deprecated.

R/ggplotly.R

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,10 @@ gg2list <- function(p, width = NULL, height = NULL,
686686
ticktext <- rng[[xy]]$get_labels %()% rng[[paste0(xy, ".labels")]]
687687
tickvals <- rng[[xy]]$break_positions %()% rng[[paste0(xy, ".major")]]
688688

689+
# https://github.com/tidyverse/ggplot2/pull/3566#issuecomment-565085809
690+
ticktext <- ticktext[!is.na(ticktext)]
691+
tickvals <- tickvals[!is.na(tickvals)]
692+
689693
axisObj <- list(
690694
# TODO: log type?
691695
type = if (isDateType) "date" else if (isDiscreteType) "category" else "linear",
@@ -1137,22 +1141,28 @@ unitConvert <- function(u, to = c("npc", "pixels"), type = c("x", "y", "height",
11371141
# from R, but it seems 96 is a reasonable assumption.
11381142
mm2pixels <- function(u) {
11391143
u <- verifyUnit(u)
1140-
if (attr(u, "unit") != "mm") {
1141-
stop("Unit must be in millimeters")
1144+
if (any(getUnitType(u) != "mm")) {
1145+
stop("All units must be in millimeters")
11421146
}
11431147
(as.numeric(u) * 96) / 25.4
11441148
}
1145-
1149+
11461150
verifyUnit <- function(u) {
1147-
# the default unit in ggplot2 is millimeters (unless it's element_text())
1148-
if (is.null(attr(u, "unit"))) {
1149-
u <- if (inherits(u, "element")) {
1150-
grid::unit(u$size %||% 0, "points")
1151-
} else {
1152-
grid::unit(u %||% 0, "mm")
1153-
}
1151+
if (grid::is.unit(u)) return(u)
1152+
1153+
## the default unit in ggplot2 is millimeters (unless it's element_text())
1154+
if (inherits(u, "element")) {
1155+
grid::unit(u$size %||% 0, "points")
1156+
} else {
1157+
grid::unit(u %||% 0, "mm")
11541158
}
1155-
u
1159+
}
1160+
1161+
# Use public API for getting the unit's type, if available
1162+
# https://github.com/ropensci/plotly/pull/1646#issue-331268260
1163+
getUnitType <- function(u) {
1164+
tryNULL(get("unitType", envir = asNamespace("grid"))(u)) %||%
1165+
attr(u, "unit")
11561166
}
11571167

11581168
# detect a blank theme element

R/helpers.R

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,15 +185,18 @@ plotly_empty <- function(...) {
185185
}
186186

187187

188-
#' Convert a raster object to a data URI
188+
#' Encode a raster object as a data URI
189189
#'
190-
#' Convenient embedding images via [layout()]
191-
#' \href{images}{https://plot.ly/r/reference/#layout-images}.
190+
#' Encode a raster object as a data URI, which is suitable for
191+
#' use with `layout()` \href{https://plot.ly/r/reference/#layout-images}{images}.
192+
#' This is especially convenient for embedding raster images on a plot in
193+
#' a self-contained fashion (i.e., so they don't depend on external URL links).
192194
#'
193195
#' @param r an object coercable to a raster object via [as.raster()]
194196
#' @param ... arguments passed onto [as.raster()].
195197
#' @author Carson Sievert
196198
#' @export
199+
#' @references <https://plotly-r.com/embedding-images.html>
197200
#' @examples
198201
#'
199202
#' # a red gradient (from ?as.raster)

R/layers2traces.R

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@ layers2traces <- function(data, prestats_data, layout, p) {
1010
position = ggtype(y, "position")
1111
)
1212

13+
# add on plot-level mappings, if they're inherited
14+
map <- c(y$mapping, if (isTRUE(y$inherit.aes)) p$mapping)
15+
1316
# consider "calculated" aesthetics (e.g., density, count, etc)
1417
calc_aes <- y$stat$default_aes[ggfun("is_calculated_aes")(y$stat$default_aes)]
15-
map <- c(y$mapping, calc_aes)
18+
calc_aes <- calc_aes[!names(calc_aes) %in% names(map)]
1619

17-
# add on plot-level mappings, if they're inherited
18-
if (isTRUE(y$inherit.aes)) map <- c(map, p$mapping)
20+
map <- c(calc_aes, map)
1921

2022
# turn symbol (e.g., ..count..) & call (e.g. calc(count)) mappings into text labels
2123
map <- ggfun("make_labels")(map)
@@ -271,16 +273,14 @@ to_basic.GeomRect <- function(data, prestats_data, layout, params, p, ...) {
271273

272274
#' @export
273275
to_basic.GeomSf <- function(data, prestats_data, layout, params, p, ...) {
274-
275-
data[["geometry"]] <- sf::st_sfc(data[["geometry"]])
276-
data <- sf::st_as_sf(data, sf_column_name = "geometry")
276+
277+
data <- sf::st_as_sf(data)
277278
geom_type <- sf::st_geometry_type(data)
278279
# st_cast should "expand" a collection into multiple rows (one per feature)
279280
if ("GEOMETRYCOLLECTION" %in% geom_type) {
280281
data <- sf::st_cast(data)
281282
geom_type <- sf::st_geometry_type(data)
282283
}
283-
data <- remove_class(data, "sf")
284284

285285
basic_type <- dplyr::recode(
286286
as.character(geom_type),
@@ -308,6 +308,7 @@ to_basic.GeomSf <- function(data, prestats_data, layout, params, p, ...) {
308308
d[[i]] <- prefix_class(
309309
fortify_sf(d[[i]]), c(names(d)[[i]], "GeomSf")
310310
)
311+
d[[i]] <- remove_class(d[[i]], "sf")
311312
}
312313
if (length(d) == 1) d[[1]] else d
313314
}
@@ -532,7 +533,7 @@ to_basic.GeomCrossbar <- function(data, prestats_data, layout, params, p, ...) {
532533
prefix_class(to_basic.GeomSegment(middle), "GeomCrossbar")
533534
)
534535
}
535-
utils::globalVariables(c("xmin", "xmax", "y", "size"))
536+
utils::globalVariables(c("xmin", "xmax", "y", "size", "COL", "PANEL", "ROW", "yaxis"))
536537

537538
#' @export
538539
to_basic.GeomRug <- function(data, prestats_data, layout, params, p, ...) {

R/layout.R

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,15 @@ rangeslider <- function(p, start = NULL, end = NULL, ...) {
134134
config <- function(p, ..., cloud = FALSE, showSendToCloud = cloud, locale = NULL, mathjax = NULL) {
135135

136136
if (!is.null(locale)) {
137-
p$dependencies <- c(
138-
p$dependencies,
139-
list(locale_dependency(locale))
140-
)
141137
p$x$config$locale <- locale
138+
# Plotly.js defaults to US English (en-US) and includes
139+
# British English (en) in the standard bundle.
140+
if (!locale %in% c("en", "en-US")) {
141+
p$dependencies <- c(
142+
p$dependencies,
143+
list(locale_dependency(locale))
144+
)
145+
}
142146
}
143147

144148
if (!is.null(mathjax)) {

R/partial_bundles.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#' # plotly graph. In this case, we get a 3x file reduction.
2727
#' # ----------------------------------------------------------------------
2828
#'
29+
#' \dontrun{
2930
#' library(plotly)
3031
#' p <- plot_ly(x = 1:10, y = 1:10) %>% add_markers()
3132
#' save_widget <- function(p, f) {
@@ -47,7 +48,6 @@
4748
#' # heatmap (part of the cartesian bundle) doesn't...
4849
#' # ----------------------------------------------------------------------
4950
#'
50-
#' \dontrun{
5151
#' library(htmltools)
5252
#' p1 <- plot_ly(z = ~volcano) %>%
5353
#' add_heatmap() %>%

R/plotly.R

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,15 @@ as_widget <- function(x, ...) {
424424
),
425425
preRenderHook = plotly_build,
426426
dependencies = c(
427+
# phantomjs doesn't support Object.setPrototypeOf() and a
428+
# plotly.js dependency (buffer) uses it to detect TypedArray support.
429+
# Thus, we add a polyfill if this is running in shinytest, but otherwise
430+
# we shouldn't need it because Object.setPrototypeOf() is pretty widely supported
431+
# https://github.com/plotly/plotly.js/issues/4556#issuecomment-583061419
432+
# https://caniuse.com/#search=setPrototypeOf
433+
if (isTRUE(getOption("shiny.testmode"))) {
434+
list(setPrototypeOfPolyfill())
435+
},
427436
list(typedArrayPolyfill()),
428437
crosstalk::crosstalkLibs(),
429438
list(plotlyHtmlwidgetsCSS()),
@@ -432,6 +441,17 @@ as_widget <- function(x, ...) {
432441
)
433442
}
434443

444+
setPrototypeOfPolyfill <- function() {
445+
htmltools::htmlDependency(
446+
name = "setprototypeof",
447+
version = "0.1",
448+
package = "plotly",
449+
src = dependency_dir("setprototypeof"),
450+
script = "setprototypeof.js",
451+
all_files = FALSE
452+
)
453+
}
454+
435455
typedArrayPolyfill <- function() {
436456
htmltools::htmlDependency(
437457
name = "typedarray",
@@ -446,7 +466,7 @@ typedArrayPolyfill <- function() {
446466
plotlyMainBundle <- function() {
447467
htmltools::htmlDependency(
448468
name = "plotly-main",
449-
version = "1.49.4",
469+
version = "1.52.2",
450470
package = "plotly",
451471
src = dependency_dir("plotlyjs"),
452472
script = "plotly-latest.min.js",

R/plotly_build.R

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ plotly_build.plotly <- function(p, registerFrames = TRUE) {
112112
if (!grepl("scatter|choropleth", tr[["type"]] %||% "scatter")) {
113113
stop("Cant add a '", tr[["type"]], "' trace to a map object", call. = FALSE)
114114
}
115-
if (is_mapbox(p)) tr[["type"]] <- "scattermapbox"
115+
if (is_mapbox(p)) tr[["type"]] <- tr[["type"]] %||% "scattermapbox"
116116
if (is_geo(p)) {
117117
tr[["type"]] <- if (!is.null(tr[["z"]])) "choropleth" else "scattergeo"
118118
}
@@ -280,10 +280,12 @@ plotly_build.plotly <- function(p, registerFrames = TRUE) {
280280
)
281281
for (i in x$.plotlyVariableMapping) {
282282
# try to reduce the amount of data we have to send for non-positional scales
283-
x[[i]] <- structure(
284-
if (i %in% npscales()) uniq(d[[i]]) else d[[i]],
285-
class = oldClass(x[[i]])
286-
)
283+
entry <- if (i %in% npscales()) uniq(d[[i]]) else d[[i]]
284+
if (is.null(entry)) {
285+
x[[i]] <- NULL
286+
} else {
287+
x[[i]] <- structure(entry, class = oldClass(x[[i]]))
288+
}
287289
}
288290
x
289291
})
@@ -1031,7 +1033,7 @@ coerce_attr_defaults <- function(trace, layout) {
10311033
if (length(trace[["stroke"]]) && !is.default(trace[["stroke"]])) {
10321034
trace$span <- trace[["span"]] %||% default(I(1))
10331035
}
1034-
if (trace[["type"]] %in% c("sunburst", "pie")) {
1036+
if (trace[["type"]] %in% c("sunburst", "pie", "treemap")) {
10351037
# As of v1.46.1, paper_bgcolor defaults to '#fff' which
10361038
# col2rgb() can't parse, but expands to '#ffffff'
10371039
# https://stackoverflow.com/a/2899224/1583084

R/sf.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ fortify_sf <- function(model, ...) {
1111
# the coordinate belongs; for POINT this is absent (each coordinate is a feature),
1212
# for LINESTRING L1 refers to the feature, for MULTIPOLYGON L1 refers to the main
1313
# ring or holes, L2 to the ring id in the MULTIPOLYGON, and L3 to the simple feature.
14-
coords <- sf::st_coordinates(model$geometry)
14+
coords <- sf::st_coordinates(sf::st_geometry(model))
1515
colnames(coords) <- tolower(colnames(coords))
1616
lcols <- grep("^l", colnames(coords))
1717

0 commit comments

Comments
 (0)