@@ -199,7 +199,9 @@ gg2list <- function(p){
199
199
layout <- list ()
200
200
trace.list <- list ()
201
201
# # Before building the ggplot, we would like to add aes(name) to
202
- # # figure out what the object group is later.
202
+ # # figure out what the object group is later. This also copies any
203
+ # # needed global aes/data values to each layer, so we do not have to
204
+ # # worry about combining global and layer-specific aes/data later.
203
205
for (layer.i in seq_along(p $ layers )){
204
206
layer.aes <- p $ layers [[layer.i ]]$ mapping
205
207
to.copy <- names(p $ mapping )[! names(p $ mapping ) %in% names(layer.aes )]
@@ -208,6 +210,9 @@ gg2list <- function(p){
208
210
name.names <- sprintf(" %s.name" , mark.names )
209
211
layer.aes [name.names ] <- layer.aes [mark.names ]
210
212
p $ layers [[layer.i ]]$ mapping <- layer.aes
213
+ if (! is.data.frame(p $ layers [[layer.i ]]$ data )){
214
+ p $ layers [[layer.i ]]$ data <- p $ data
215
+ }
211
216
}
212
217
# # Extract data from built ggplots
213
218
built <- ggplot2 :: ggplot_build(p )
@@ -221,10 +226,14 @@ gg2list <- function(p){
221
226
df <- built $ data [[i ]]
222
227
223
228
# # Test fill and color to see if they encode a quantitative
224
- # # variable. In that case, we do not make traces for separate
225
- # # colors, since there are too many!
229
+ # # variable. This may be useful for several reasons: (1) it is
230
+ # # sometimes possible to plot several different colors in the same
231
+ # # trace (e.g. points), and that is faster for large numbers of
232
+ # # data points and colors; (2) factors on x or y axes should be
233
+ # # sent to plotly as characters, not as numeric data (which is
234
+ # # what ggplot_build gives us).
226
235
misc <- list ()
227
- for (a in c(" fill" , " colour" )){
236
+ for (a in c(" fill" , " colour" , " x " , " y " )){
228
237
fun.name <- sprintf(" scale_%s_continuous" , a )
229
238
fun <- get(fun.name )
230
239
misc $ is.continuous [[a ]] <- tryCatch({
@@ -318,7 +327,11 @@ gg2list <- function(p){
318
327
ax.list $ tickfont <- theme2font(tick.text )
319
328
title.text <- e(s(" axis.title.%s" ))
320
329
ax.list $ titlefont <- theme2font(title.text )
321
- ax.list $ type <- " linear" # # TODO: log scales?
330
+ ax.list $ type <- if (misc $ is.continuous [[xy ]]){
331
+ " linear"
332
+ }else {# # TODO: time scales?
333
+ " category"
334
+ }
322
335
# # Lines drawn around the plot border:
323
336
ax.list $ showline <- ifelse(is.blank(" panel.border" ), FALSE , TRUE )
324
337
ax.list $ linecolor <- toRGB(theme.pars $ panel.border $ colour )
@@ -360,6 +373,18 @@ layer2traces <- function(l, d, misc){
360
373
# # needed for when group, etc. is an expression.
361
374
g $ aes <- sapply(l $ mapping , function (k ) as.character(as.expression(k )))
362
375
376
+ # # For factors on the axes, we should take the values from the
377
+ # # original data.
378
+ for (axis.name in c(" x" , " y" )){
379
+ if (! misc $ is.continuous [[axis.name ]]){
380
+ aes.names <- paste0(axis.name , c(" " , " end" , " min" , " max" ))
381
+ aes.used <- aes.names [aes.names %in% names(g $ aes )]
382
+ if (length(aes.used )){
383
+ col.used <- g $ aes [aes.used ]
384
+ g $ data [aes.used ] <- l $ data [col.used ]
385
+ }
386
+ }
387
+ }
363
388
# # use un-named parameters so that they will not be exported
364
389
# # to JSON as a named object, since that causes problems with
365
390
# # e.g. colour.
@@ -446,6 +471,12 @@ layer2traces <- function(l, d, misc){
446
471
for (data.i in seq_along(data.list )){
447
472
data.params <- data.list [[data.i ]]
448
473
tr <- do.call(getTrace , data.params )
474
+ for (v.name in c(" x" , " y" )){
475
+ vals <- tr [[v.name ]]
476
+ if (is.na(vals [length(vals )])){
477
+ tr [[v.name ]] <- vals [- length(vals )]
478
+ }
479
+ }
449
480
name.names <- grep(" [.]name$" , names(data.params $ params ), value = TRUE )
450
481
if (length(name.names )){
451
482
for (a.name in name.names ){
0 commit comments