Skip to content

Commit db377e0

Browse files
committed
Merge branch 'master' into sf-grob
2 parents bd20ce9 + 0beb525 commit db377e0

20 files changed

+238
-186
lines changed

NEWS.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22

33
## NEW FEATURES & IMPROVEMENTS
44

5+
* Upgraded to plotly.js v1.33.1. A _huge_ amount of features and improvements have been made since v1.29.2 (i.e., the version included in the last CRAN release of the R package - v4.7.1). Highlights include a complete re-write of `scattergl` to make it nearly feature complete with `scatter`, localization of text rendering (i.e., international translations), and two new trace types (`violin` & `table`). Read more about the v1.32.0 release [here](https://codeburst.io/notes-from-the-latest-plotly-js-release-b035a5b43e21) and the complete list of changes [here](https://github.com/plotly/plotly.js/releases).
6+
* The selection mode can now switch from 'transient' to 'persistent' by holding the 'shift' key. It's still possible to _force_ persistent selection by setting `persistent = TRUE` in `highlight()`, but `persistent = FALSE` (the default) is now recommended since it allows one to switch between [persistent/transient selection](https://plotly-book.cpsievert.me/linking-views-without-shiny.html#transient-versus-persistent-selection) in the browser, rather than at the command line.
7+
58
## CHANGES
69

710
* The `elementId` field is no longer populated, which fixes the "Ignoring explicitly provided widget ID" warning in shiny applications (see #985).
8-
* Upgraded to plotly.js v1.31.2 -- https://github.com/plotly/plotly.js/releases/tag/v1.31.2
911

1012
## BUG FIXES
1113

12-
Fixed algorithm for coercing the proposed layout to the plot schema (see #1156).
14+
* Fixed algorithm for coercing the proposed layout to the plot schema (see #1156).
1315

1416
# 4.7.1
1517

R/ggplotly.R

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,20 @@
4646
#' # linked scatterplot brushing
4747
#' library(crosstalk)
4848
#' d <- SharedData$new(mtcars)
49-
#' subplot(
50-
#' qplot(data = d, x = mpg, y = wt),
51-
#' qplot(data = d, x = mpg, y = vs)
52-
#' )
49+
#' qplot(data = d, x = mpg, y = wt) %>%
50+
#' subplot(qplot(data = d, x = mpg, y = vs)) %>%
51+
#' layout(title = "Click and drag to select points") %>%
52+
#' highlight("plotly_selected")
53+
#'
5354
#'
5455
#' # more brushing (i.e. highlighting) examples
5556
#' demo("crosstalk-highlight-ggplotly", package = "plotly")
5657
#'
5758
#' # client-side linked brushing in a scatterplot matrix
5859
#' SharedData$new(iris) %>%
5960
#' GGally::ggpairs(aes(colour = Species), columns = 1:4) %>%
60-
#' ggplotly(tooltip = c("x", "y", "colour"))
61+
#' ggplotly(tooltip = c("x", "y", "colour")) %>%
62+
#' highlight("plotly_selected")
6163
#' }
6264
#'
6365
ggplotly <- function(p = ggplot2::last_plot(), width = NULL, height = NULL,
@@ -592,7 +594,7 @@ gg2list <- function(p, width = NULL, height = NULL,
592594
axisText <- theme_el("axis.text")
593595
axisTitle <- theme_el("axis.title")
594596
axisLine <- theme_el("axis.line")
595-
panelGrid <- theme_el("panel.grid.major")
597+
panelGrid <- theme_el("panel.grid.major") %||% theme_el("panel.grid")
596598
stripText <- theme_el("strip.text")
597599

598600
axisName <- lay[, paste0(xy, "axis")]
@@ -623,9 +625,9 @@ gg2list <- function(p, width = NULL, height = NULL,
623625
d$x <- scales::rescale(d$x, rng$x_range, from = c(0, 1))
624626
d$y <- scales::rescale(d$y, rng$y_range, from = c(0, 1))
625627
params <- list(
626-
colour = theme$panel.grid.major$colour,
627-
size = theme$panel.grid.major$size,
628-
linetype = theme$panel.grid.major$linetype
628+
colour = panelGrid$colour,
629+
size = panelGrid$size,
630+
linetype = panelGrid$linetype
629631
)
630632
grill <- geom2trace.GeomPath(d, params)
631633
grill$hoverinfo <- "none"
@@ -711,20 +713,28 @@ gg2list <- function(p, width = NULL, height = NULL,
711713
)
712714

713715
# set scaleanchor/scaleratio if these are fixed coordinates
716+
# the logic here is similar to what p$coordinates$aspect() does,
717+
# but the ratio is scaled to the data range by plotly.js
714718
fixed_coords <- c("CoordSf", "CoordFixed", "CoordMap", "CoordQuickmap")
715719
if (inherits(p$coordinates, fixed_coords)) {
716720
axisObj$scaleanchor <- anchor
717721
ratio <- p$coordinates$ratio %||% 1
718-
# a la CoordSf$aspect
722+
axisObj$scaleratio <- if (xy == "y") ratio else 1 / ratio
723+
719724
if (inherits(p$coordinates, "CoordSf")) {
720725
if (isTRUE(sf::st_is_longlat(rng$crs))) {
721726
ratio <- cos(mean(rng$y_range) * pi/180)
722727
}
728+
# note how ratio is flipped in CoordSf$aspect() vs CoordFixed$aspect()
729+
axisObj$scaleratio <- if (xy == "y") 1 / ratio else ratio
723730
}
724-
axisObj$scaleratio <- if (xy == "y") ratio else 1 / ratio
725731
}
726732

727-
# TODO: should we implement aspect ratios?
733+
# TODO: seems like we _could_ support this with scaleanchors,
734+
# but inverse transform by the panel ranges?
735+
# also, note how aspect.ratio overwrites fixed coordinates:
736+
# ggplot(mtcars, aes(wt, mpg)) + geom_point() + coord_fixed(0.5)
737+
# ggplot(mtcars, aes(wt, mpg)) + geom_point() + coord_fixed(0.5) + theme(aspect.ratio = 1)
728738
if (!is.null(theme$aspect.ratio)) {
729739
warning(
730740
"Aspect ratios aren't yet implemented, but you can manually set",

R/highlight.R

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@
2828
#' (i.e., clicking the home button in the modebar) or whenever the height/width
2929
#' of the plot changes.
3030
#' }
31-
#' @param persistent should selections persist (i.e., accumulate)?
31+
#' @param persistent should selections persist (i.e., accumulate)? We often
32+
#' refer to the default (`FALSE`) as a 'transient' selection mode;
33+
#' which is recommended, because one may switch from 'transient' to
34+
#' 'persistent' selection by holding the shift key.
3235
#' @param dynamic should a widget for changing selection colors be included?
3336
#' @param color character string of color(s) to use for
3437
#' highlighting selections. See [toRGB()] for valid color
@@ -41,6 +44,7 @@
4144
#' @param opacityDim a number between 0 and 1 used to reduce the
4245
#' opacity of non-selected traces (by multiplying with the existing opacity).
4346
#' @param selected attributes of the selection, see [attrs_selected()].
47+
#' @param unselected attributes of the non-selected marks, see [attrs_unselected()].
4448
#' @param ... currently not supported.
4549
#' @export
4650
#' @author Carson Sievert
@@ -56,13 +60,11 @@
5660
#' d <- SharedData$new(txhousing, ~city)
5761
#' p <- ggplot(d, aes(date, median, group = city)) + geom_line()
5862
#' gg <- ggplotly(p, tooltip = "city")
59-
#' highlight(gg, persistent = TRUE, dynamic = TRUE)
63+
#' highlight(gg, dynamic = TRUE)
6064
#'
6165
#' # supply custom colors to the brush
6266
#' cols <- toRGB(RColorBrewer::brewer.pal(3, "Dark2"), 0.5)
63-
#' highlight(
64-
#' gg, on = "plotly_hover", color = cols, persistent = TRUE, dynamic = TRUE
65-
#' )
67+
#' highlight(gg, on = "plotly_hover", color = cols, dynamic = TRUE)
6668
#'
6769
#' # Use attrs_selected() for complete control over the selection appearance
6870
#' # note any relevant colors you specify here should override the color argument
@@ -72,10 +74,7 @@
7274
#' marker = list(symbol = "x")
7375
#' )
7476
#'
75-
#' highlight(
76-
#' layout(gg, showlegend = TRUE),
77-
#' selected = s, persistent = TRUE
78-
#' )
77+
#' highlight(layout(gg, showlegend = TRUE), selected = s)
7978
#'
8079

8180
highlight <- function(p, on = "plotly_click", off,
@@ -102,12 +101,12 @@ highlight <- function(p, on = "plotly_click", off,
102101
stop("opacityDim must be between 0 and 1", call. = FALSE)
103102
}
104103
if (dynamic && length(color) < 2) {
105-
message("Adding more colors to the selection color palette")
104+
message("Adding more colors to the selection color palette.")
106105
color <- c(color, RColorBrewer::brewer.pal(4, "Set1"))
107106
}
108107
if (!dynamic && length(color) > 1) {
109108
warning(
110-
"Can only use a single color for selections when dynamic=FALSE",
109+
"Can only use a single color for selections when `dynamic = FALSE`.",
111110
call. = FALSE
112111
)
113112
color <- color[1]
@@ -137,6 +136,14 @@ highlight <- function(p, on = "plotly_click", off,
137136
off <- default(off_default %||% "plotly_relayout")
138137
}
139138

139+
if (isTRUE(persistent)) {
140+
message(
141+
"We recommend setting `persistent` to `FALSE` (the default) because ",
142+
"persistent selection mode can now be used by holding the shift key ",
143+
"(while triggering the `on` event)."
144+
)
145+
}
146+
140147
# main (non-plotly.js) spec passed along to HTMLwidgets.renderValue()
141148
p$x$highlight <- list(
142149
# NULL may be used to disable on/off events

R/plotly.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ typedArrayPolyfill <- function() {
373373
# and bundle size at print time.
374374
plotlyMainBundle <- function() {
375375
htmltools::htmlDependency(
376-
"plotlyjs", "1.31.2.9000",
376+
"plotlyjs", "1.33.1",
377377
src = depPath("plotlyjs"),
378378
script = "plotly-latest.min.js",
379379
stylesheet = "plotly-htmlwidgets.css"

R/sysdata.rda

4.64 KB
Binary file not shown.

R/utils.R

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -267,12 +267,6 @@ supply_defaults <- function(p) {
267267
supply_highlight_attrs <- function(p) {
268268
# set "global" options via crosstalk variable
269269
p$x$highlight <- p$x$highlight %||% highlight_defaults()
270-
p <- htmlwidgets::onRender(
271-
p, sprintf(
272-
"function(el, x) { var ctConfig = crosstalk.var('plotlyCrosstalkOpts').set(%s); }",
273-
to_JSON(p$x$highlight)
274-
)
275-
)
276270

277271
# defaults are now populated, allowing us to populate some other
278272
# attributes such as the selectize widget definition

demo/crosstalk-highlight-binned-target-a.R

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,24 @@ library(crosstalk)
33
library(plotly)
44

55
d <- SharedData$new(mpg)
6-
dots <- plot_ly(d, color = ~class, x = ~displ, y = ~cyl)
7-
boxs <- plot_ly(d, color = ~class, x = ~class, y = ~cty) %>% add_boxplot()
8-
bars <- plot_ly(d, x = ~class, color = ~class)
6+
dots <- plot_ly(d, colors = "Set1", color = ~class, x = ~displ, y = ~cyl) %>%
7+
layout(
8+
xaxis = list(title = "Engine displacement"),
9+
yaxis = list(title = "Number of cylinders")
10+
)
11+
boxs <- plot_ly(d, colors = "Set1", color = ~class, x = ~class, y = ~cty) %>%
12+
add_boxplot() %>%
13+
layout(
14+
xaxis = list(title = ""),
15+
yaxis = list(title = "Miles per gallon (city)")
16+
)
17+
bars <- plot_ly(d, colors = "Set1", x = ~class, color = ~class)
918

1019
subplot(dots, boxs, titleX = TRUE, titleY = TRUE) %>%
1120
subplot(bars, nrows = 2, titleX = TRUE, titleY = TRUE) %>%
1221
layout(
13-
title = "Click and drag on scatterplot",
22+
title = "Dynamic 2-way ANOVA (click & drag on scatterplot)",
1423
barmode = "overlay",
1524
showlegend = FALSE
1625
) %>%
17-
highlight("plotly_selected")
26+
highlight("plotly_selected", opacityDim = 0.6)

demo/crosstalk-highlight-binned-target-c.R

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,4 @@ p2 <- plot_ly(tx, x = ~median, color = I("black")) %>%
1010

1111
subplot(gg1, p2, titleX = TRUE, titleY = TRUE) %>%
1212
layout(barmode = "overlay") %>%
13-
highlight(
14-
dynamic = TRUE, persistent = TRUE,
15-
selected = attrs_selected(opacity = 0.3)
16-
)
13+
highlight(dynamic = TRUE, selected = attrs_selected(opacity = 0.3))

demo/crosstalk-highlight-epl-2.R

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
library(engsoccerdata)
2+
library(dplyr)
3+
library(tidyr)
4+
library(plotly)
5+
library(crosstalk)
6+
7+
# shape data into desired format
8+
dat <- england %>%
9+
gather(location, team, home, visitor) %>%
10+
# focus on tier 1 teams that are still playing in 2015
11+
filter(team %in% maketable_eng(england, 2015, 1)[["team"]]) %>%
12+
mutate(
13+
pts = ifelse(location == "home" & goaldif > 0, 3,
14+
ifelse(location == "away" & goaldif < 0, 3, 1))
15+
) %>%
16+
arrange(Date) %>%
17+
group_by(Season, team) %>%
18+
mutate(gameno = row_number(), cumpts = cumsum(pts)) %>%
19+
ungroup() %>%
20+
group_by(gameno) %>%
21+
mutate(meanP = mean(cumpts)) %>%
22+
filter(Season > 2006)
23+
24+
sd <- SharedData$new(dat, ~team, "Select a team")
25+
26+
# a 'wormchart' like fig 8 here http://www.gradaanwr.net/wp-content/uploads/2016/06/dataApr16.pdf
27+
p <- ggplot(sd, aes(x = gameno, y = cumpts - meanP)) +
28+
geom_line(aes(group = team), alpha = 0.5) +
29+
facet_wrap(~ Season, ncol = 3) +
30+
labs(
31+
title = "English Premier League Performance",
32+
x = "Game in season",
33+
y = "Cumulative points (above/below) average"
34+
)
35+
36+
gg <- ggplotly(p, width = 1050, height = 600, tooltip = "team")
37+
38+
highlight(
39+
gg,
40+
dynamic = TRUE,
41+
selectize = TRUE,
42+
color = RColorBrewer::brewer.pal(12, "Paired")
43+
)

demo/crosstalk-highlight-ggplotly.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ d <- SharedData$new(txhousing, ~city, "Select a city")
66
p <- ggplot(d, aes(date, median, group = city)) + geom_line()
77
ggplotly(p, tooltip = "city") %>%
88
layout(title = "Click on a line to highlight a year") %>%
9-
highlight(dynamic = TRUE, selectize = TRUE, persistent = TRUE)
9+
highlight(dynamic = TRUE, selectize = TRUE)
1010

1111
# crosstalk keys are automatically added to the group aesthetic...
1212
# if you want to avoid adding the key to group for a layer,

0 commit comments

Comments
 (0)