@@ -208,7 +208,9 @@ gg2list <- function(p){
208
208
layout <- list ()
209
209
trace.list <- list ()
210
210
# # Before building the ggplot, we would like to add aes(name) to
211
- # # figure out what the object group is later.
211
+ # # figure out what the object group is later. This also copies any
212
+ # # needed global aes/data values to each layer, so we do not have to
213
+ # # worry about combining global and layer-specific aes/data later.
212
214
for (layer.i in seq_along(p $ layers )){
213
215
layer.aes <- p $ layers [[layer.i ]]$ mapping
214
216
to.copy <- names(p $ mapping )[! names(p $ mapping ) %in% names(layer.aes )]
@@ -217,6 +219,9 @@ gg2list <- function(p){
217
219
name.names <- sprintf(" %s.name" , mark.names )
218
220
layer.aes [name.names ] <- layer.aes [mark.names ]
219
221
p $ layers [[layer.i ]]$ mapping <- layer.aes
222
+ if (! is.data.frame(p $ layers [[layer.i ]]$ data )){
223
+ p $ layers [[layer.i ]]$ data <- p $ data
224
+ }
220
225
}
221
226
# # Extract data from built ggplots
222
227
built <- ggplot2 :: ggplot_build(p )
@@ -230,10 +235,14 @@ gg2list <- function(p){
230
235
df <- built $ data [[i ]]
231
236
232
237
# # Test fill and color to see if they encode a quantitative
233
- # # variable. In that case, we do not make traces for separate
234
- # # colors, since there are too many!
238
+ # # variable. This may be useful for several reasons: (1) it is
239
+ # # sometimes possible to plot several different colors in the same
240
+ # # trace (e.g. points), and that is faster for large numbers of
241
+ # # data points and colors; (2) factors on x or y axes should be
242
+ # # sent to plotly as characters, not as numeric data (which is
243
+ # # what ggplot_build gives us).
235
244
misc <- list ()
236
- for (a in c(" fill" , " colour" )){
245
+ for (a in c(" fill" , " colour" , " x " , " y " )){
237
246
fun.name <- sprintf(" scale_%s_continuous" , a )
238
247
fun <- get(fun.name )
239
248
misc $ is.continuous [[a ]] <- tryCatch({
@@ -327,7 +336,11 @@ gg2list <- function(p){
327
336
ax.list $ tickfont <- theme2font(tick.text )
328
337
title.text <- e(s(" axis.title.%s" ))
329
338
ax.list $ titlefont <- theme2font(title.text )
330
- ax.list $ type <- " linear" # # TODO: log scales?
339
+ ax.list $ type <- if (misc $ is.continuous [[xy ]]){
340
+ " linear"
341
+ }else {# # TODO: time scales?
342
+ " category"
343
+ }
331
344
# # Lines drawn around the plot border:
332
345
ax.list $ showline <- ifelse(is.blank(" panel.border" ), FALSE , TRUE )
333
346
ax.list $ linecolor <- toRGB(theme.pars $ panel.border $ colour )
@@ -368,7 +381,19 @@ layer2traces <- function(l, d, misc){
368
381
data = d )
369
382
# # needed for when group, etc. is an expression.
370
383
g $ aes <- sapply(l $ mapping , function (k ) as.character(as.expression(k )))
371
-
384
+
385
+ # # For factors on the axes, we should take the values from the
386
+ # # original data.
387
+ for (axis.name in c(" x" , " y" )){
388
+ if (! misc $ is.continuous [[axis.name ]]){
389
+ aes.names <- paste0(axis.name , c(" " , " end" , " min" , " max" ))
390
+ aes.used <- aes.names [aes.names %in% names(g $ aes )]
391
+ if (length(aes.used )){
392
+ col.used <- g $ aes [aes.used ]
393
+ g $ data [aes.used ] <- l $ data [col.used ]
394
+ }
395
+ }
396
+ }
372
397
# # use un-named parameters so that they will not be exported
373
398
# # to JSON as a named object, since that causes problems with
374
399
# # e.g. colour.
@@ -455,6 +480,12 @@ layer2traces <- function(l, d, misc){
455
480
for (data.i in seq_along(data.list )){
456
481
data.params <- data.list [[data.i ]]
457
482
tr <- do.call(getTrace , data.params )
483
+ for (v.name in c(" x" , " y" )){
484
+ vals <- tr [[v.name ]]
485
+ if (is.na(vals [length(vals )])){
486
+ tr [[v.name ]] <- vals [- length(vals )]
487
+ }
488
+ }
458
489
name.names <- grep(" [.]name$" , names(data.params $ params ), value = TRUE )
459
490
if (length(name.names )){
460
491
for (a.name in name.names ){
0 commit comments