Skip to content

Commit 70ca674

Browse files
committed
safeguard against missing values in subplot; ggplotly is now generic with ggmatrix/ggplot methods
1 parent b6fb58e commit 70ca674

File tree

5 files changed

+39
-37
lines changed

5 files changed

+39
-37
lines changed

NAMESPACE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ S3method(geom2trace,GeomPolygon)
1111
S3method(geom2trace,GeomText)
1212
S3method(geom2trace,GeomTile)
1313
S3method(geom2trace,default)
14+
S3method(ggplotly,ggmatrix)
15+
S3method(ggplotly,ggplot)
1416
S3method(print,figure)
1517
S3method(print,plotly)
1618
S3method(to_basic,GeomAbline)

R/ggplotly.R

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,25 @@
3232
#'
3333
ggplotly <- function(p = ggplot2::last_plot(), width = NULL, height = NULL,
3434
tooltip = "all", source = "A") {
35+
UseMethod("ggplotly")
36+
}
37+
38+
#' @export
39+
ggplotly.ggmatrix <- function(p = ggplot2::last_plot(), width = NULL,
40+
height = NULL, tooltip = "all", source = "A") {
41+
plotList <- list()
42+
for (i in seq_len(p$nrow)) {
43+
for (j in seq_len(p$ncol)) {
44+
plotList <- c(plotList, list(pm[i, j]))
45+
}
46+
}
47+
# TODO: how to show x/y titles? Should these be arguments in subplot?
48+
do.call(subplot, c(plotList, list(nrows = p$nrow)))
49+
}
50+
51+
#' @export
52+
ggplotly.ggplot <- function(p = ggplot2::last_plot(), width = NULL,
53+
height = NULL, tooltip = "all", source = "A") {
3554
l <- gg2list(p, width = width, height = height, tooltip = tooltip, source = source)
3655
hash_plot(p$data, l)
3756
}
@@ -428,10 +447,12 @@ gg2list <- function(p, width = NULL, height = NULL, tooltip = "all", source = "A
428447

429448
} # end of axis loop
430449

450+
# theme(panel.border = ) -> plotly rect shape
431451
xdom <- gglayout[[lay[, "xaxis"]]]$domain
432452
ydom <- gglayout[[lay[, "yaxis"]]]$domain
433453
border <- make_panel_border(xdom, ydom, theme)
434454
gglayout$shapes <- c(gglayout$shapes, border)
455+
435456
# facet strips -> plotly annotations
436457
if (has_facet(p)) {
437458
col_vars <- ifelse(inherits(p$facet, "wrap"), "facets", "cols")
@@ -461,25 +482,7 @@ gg2list <- function(p, width = NULL, height = NULL, tooltip = "all", source = "A
461482
strip <- make_strip_rect(xdom, ydom, theme, "right")
462483
gglayout$shapes <- c(gglayout$shapes, strip)
463484
}
464-
465-
466-
467485
}
468-
469-
470-
if (!is_blank(theme[["strip.text.x"]]) &&
471-
(inherits(p$facet, "wrap") || inherits(p$facet, "grid") && lay$ROW == 1)) {
472-
vars <- ifelse(inherits(p$facet, "wrap"), "facets", "cols")
473-
474-
475-
476-
}
477-
if (inherits(p$facet, "grid") && lay$COL == nCols && nRows > 1 &&
478-
!is_blank(theme[["strip.text.y"]])) {
479-
480-
481-
}
482-
483486
} # end of panel loop
484487

485488
# ------------------------------------------------------------------------

R/plotly.R

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,10 @@ style <- function(p = last_plot(), ..., traces = 1, evaluate = FALSE) {
232232
#' @param l a ggplot object, or a plotly object, or a list.
233233
#' @export
234234
plotly_build <- function(l = last_plot()) {
235-
#if (inherits(l, "ggmatrix"))
236-
# ggplot objects don't need any special type of handling
237-
if (ggplot2::is.ggplot(l)) return(gg2list(l))
235+
# ggplot objects (including ggmatrix) don't need any special type of handling
236+
if (inherits(l, "gg")) {
237+
return(structure(get_plot(ggplotly(l)), class = "plotly"))
238+
}
238239
l <- get_plot(l)
239240
# assume unnamed list elements are data/traces
240241
nms <- names(l)

R/subplots.R

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,16 @@ subplot <- function(..., nrows = 1, which_layout = "merge", margin = 0.02) {
3131
axes <- vapply(x$annotations, function(a) identical(a$annotationType, "axis"), logical(1))
3232
x$annotations[!axes]
3333
})
34-
# collect axis objects, and remove their titles
34+
# collect axis objects
3535
xAxes <- lapply(layouts, function(x) {
36-
xaxis <- x[grepl("^xaxis", names(x))] %||%
37-
list(xaxis = list(domain = c(0, 1), anchor = "y"))
38-
xaxis$title <- NULL
39-
xaxis
36+
x[grepl("^xaxis", names(x))] %||% list(xaxis = list(domain = c(0, 1), anchor = "y"))
4037
})
4138
yAxes <- lapply(layouts, function(x) {
42-
yaxis <- x[grepl("^yaxis", names(x))] %||%
43-
list(yaxis = list(domain = c(0, 1), anchor = "x"))
44-
yaxis$title <- NULL
45-
yaxis
39+
x[grepl("^yaxis", names(x))] %||% list(yaxis = list(domain = c(0, 1), anchor = "x"))
4640
})
41+
# remove their titles
42+
xAxes <- lapply(xAxes, function(x) lapply(x, function(y) { y$title <- NULL; y }))
43+
yAxes <- lapply(yAxes, function(x) lapply(x, function(y) { y$title <- NULL; y }))
4744
# number of x/y axes per plot
4845
xAxisN <- vapply(xAxes, length, numeric(1))
4946
yAxisN <- vapply(yAxes, length, numeric(1))
@@ -74,25 +71,27 @@ subplot <- function(..., nrows = 1, which_layout = "merge", margin = 0.02) {
7471
for (j in seq_along(xAxes[[i]])) {
7572
# before bumping axis anchor, bump trace info, where appropriate
7673
traces[[i]] <- lapply(traces[[i]], function(tr) {
74+
tr$xaxis <- tr$xaxis %||% "x"
7775
tr$xaxis[sub("axis", "", xMap[[j]]) %in% tr$xaxis] <- sub("axis", "", names(xMap[j]))
7876
tr
7977
})
8078
# bump anchors
81-
map <- yMap[yMap %in% sub("y", "yaxis", xAxes[[i]][[j]]$anchor)]
79+
map <- yMap[yMap %in% sub("y", "yaxis", xAxes[[i]][[j]]$anchor %||% "y")]
8280
xAxes[[i]][[j]]$anchor <- sub("axis", "", names(map))
8381
xAxes[[i]][[j]]$domain <- sort(scales::rescale(
84-
xAxes[[i]][[j]]$domain, xDom, from = c(0, 1)
82+
xAxes[[i]][[j]]$domain %||% c(0, 1), xDom, from = c(0, 1)
8583
))
8684
}
8785
for (j in seq_along(yAxes[[i]])) {
8886
traces[[i]] <- lapply(traces[[i]], function(tr) {
87+
tr$yaxis <- tr$yaxis %||% "y"
8988
tr$yaxis[sub("axis", "", yMap[[j]]) %in% tr$yaxis] <- sub("axis", "", names(yMap[j]))
9089
tr
9190
})
92-
map <- xMap[xMap %in% sub("x", "xaxis", yAxes[[i]][[j]]$anchor)]
91+
map <- xMap[xMap %in% sub("x", "xaxis", yAxes[[i]][[j]]$anchor %||% "x")]
9392
yAxes[[i]][[j]]$anchor <- sub("axis", "", names(map))
9493
yAxes[[i]][[j]]$domain <- sort(scales::rescale(
95-
yAxes[[i]][[j]]$domain, yDom, from = c(0, 1)
94+
yAxes[[i]][[j]]$domain %||% c(0, 1), yDom, from = c(0, 1)
9695
))
9796
}
9897
xAxes[[i]] <- setNames(xAxes[[i]], names(xMap))

tests/testthat/test-plotly-subplot.R

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,3 @@ test_that("group + [x/y]axis works", {
4444
expect_true(all(2/3 > xdom[[2]] & xdom[[2]] > 1/3))
4545
expect_true(all(1 >= xdom[[3]] & xdom[[3]] > 2/3))
4646
})
47-
48-
49-

0 commit comments

Comments
 (0)