65
65
# '
66
66
plot_ly <- function (data = data.frame (), ... , type = " scatter" ,
67
67
group , color , colors , symbol , symbols , size ,
68
- width = NULL , height = NULL , inherit = TRUE ,
68
+ width = NULL , height = NULL , inherit = FALSE ,
69
69
evaluate = FALSE ) {
70
70
# "native" plotly arguments
71
71
argz <- substitute(list (... ))
@@ -265,9 +265,6 @@ plotly_build <- function(l = last_plot()) {
265
265
# ggplot objects don't need any special type of handling
266
266
if (is.ggplot(l )) return (gg2list(l ))
267
267
l <- get_plot(l )
268
- # plots without NSE don't need it either
269
- nmz <- c(lapply(l $ data , names ), lapply(l $ layout , names ), lapply(l $ style , names ))
270
- if (! all(c(" args" , " env" ) %in% unlist(nmz ))) return (structure(l , class = unique(" plotly" , class(l ))))
271
268
# assume unnamed list elements are data/traces
272
269
nms <- names(l )
273
270
idx <- nms %in% " "
@@ -276,14 +273,20 @@ plotly_build <- function(l = last_plot()) {
276
273
} else if (any(idx )) {
277
274
c(data = c(l $ data , l [idx ]), l [! idx ])
278
275
} else l
279
- dats <- list ()
276
+ # carry over unevaluated arguments, if necessary
277
+ if (length(l $ data ) > 1 && isTRUE(l $ data [[1 ]]$ inherit ) && should_eval(l $ data [[1 ]])) {
278
+ for (i in seq.int(2 , length(l $ data ))) {
279
+ l $ data [[i ]] <- modifyList(l $ data [[i ]], l $ data [[1 ]])
280
+ }
281
+ }
282
+ # 'x' is the same as 'l', but with arguments evaluated
283
+ # this is ugly, but we don't know how many traces we'll have until
284
+ # we evaluate arguments and call traceify() (or similar)
285
+ x <- list ()
280
286
for (i in seq_along(l $ data )) {
281
287
d <- l $ data [[i ]]
282
- # if appropriate, evaluate trace arguments in a suitable environment
283
- idx <- names(d ) %in% c(" args" , " env" , " enclos" )
284
- if (sum(idx ) == 3 ) {
285
- dat <- c(d [! idx ], eval(d $ args , as.list(d $ env , all.names = TRUE ), d $ enclos ))
286
- dat [c(" args" , " env" , " enclos" )] <- NULL
288
+ if (should_eval(d )) {
289
+ dat <- do_eval(d )
287
290
# start processing specially named arguments
288
291
s <- dat [[" size" ]]
289
292
if (! is.null(s )) {
@@ -309,21 +312,14 @@ plotly_build <- function(l = last_plot()) {
309
312
has_group <- ! is.null(dat [[" group" ]])
310
313
if (has_color ) {
311
314
title <- as.list(d $ args )[[" color" ]] %|| % as.list(d $ args )[[" z" ]] %|| % " "
312
- dats <- c(dats , colorize(dat , title ))
315
+ x $ data <- c(x $ data , colorize(dat , title ))
313
316
}
314
317
# TODO: add a legend title (is this only possible via annotations?!?)
315
- if (has_symbol ) dats <- c(dats , symbolize(dat ))
316
- if (has_group ) dats <- c(dats , traceify(dat , " group" ))
317
- if (! has_color && ! has_symbol && ! has_group ) dats <- c(dats , list (dat ))
318
+ if (has_symbol ) x $ data <- c(x $ data , symbolize(dat ))
319
+ if (has_group ) x $ data <- c(x $ data , traceify(dat , " group" ))
320
+ if (! has_color && ! has_symbol && ! has_group ) x $ data <- c(x $ data , list (dat ))
318
321
} else {
319
- dats <- c(dats , list (d ))
320
- }
321
- }
322
- x <- list (data = dats )
323
- # carry over properties/data from first trace (if appropriate)
324
- if (length(x $ data ) > 1 && isTRUE(l $ data [[1 ]]$ inherit )) {
325
- for (i in seq.int(2 , length(x $ data ))) {
326
- x $ data [[i ]] <- modifyList(x $ data [[1 ]], x $ data [[i ]])
322
+ x $ data <- c(x $ data , list (d ))
327
323
}
328
324
}
329
325
# layout() tacks on an unnamed list element to potentially pre-existing
@@ -334,24 +330,19 @@ plotly_build <- function(l = last_plot()) {
334
330
# TODO: does this always preserve the correct order to layouts?
335
331
# (important since we use modifyList at a later point)
336
332
l $ layout <- c(list (l $ layout [! idx ]), l $ layout [idx ])
333
+ } else {
334
+ l $ layout <- list (l $ layout )
337
335
}
338
336
for (i in seq_along(l $ layout )) {
339
- layout <- l $ layout [[i ]]
340
- idx <- names(layout ) %in% c(" args" , " env" , " enclos" )
341
- x $ layout [[i ]] <- if (sum(idx ) == 3 ) {
342
- c(layout [! idx ], eval(layout $ args , as.list(layout $ env , all.names = TRUE ), layout $ enclos ))
343
- } else {
344
- layout
345
- }
337
+ x $ layout [[i ]] <- perform_eval(l $ layout [[i ]])
346
338
}
347
339
x $ layout <- Reduce(modifyList , x $ layout )
348
340
# if style is not null, use it to modify existing traces
349
341
if (! is.null(l $ style )) {
350
342
for (i in seq_along(l $ style )) {
351
- sty <- l $ style [[i ]]
352
- idx <- names(sty ) %in% c(" args" , " env" , " enclos" )
353
- new_sty <- if (sum(idx ) == 3 ) c(sty [! idx ], eval(sty $ args , as.list(sty $ env , all.names = TRUE ), sty $ enclos )) else sty
354
- for (k in sty $ traces ) x $ data [[k ]] <- modifyList(x $ data [[k ]], new_sty )
343
+ sty <- perform_eval(l $ style [[i ]])
344
+ for (k in l $ style [[i ]]$ traces )
345
+ x $ data [[k ]] <- modifyList(x $ data [[k ]], sty )
355
346
}
356
347
}
357
348
# add appropriate axis title (if they don't already exist)
0 commit comments