@@ -208,7 +208,9 @@ gg2list <- function(p){
208208 layout <- list ()
209209 trace.list <- list ()
210210 # # 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.
212214 for (layer.i in seq_along(p $ layers )){
213215 layer.aes <- p $ layers [[layer.i ]]$ mapping
214216 to.copy <- names(p $ mapping )[! names(p $ mapping ) %in% names(layer.aes )]
@@ -217,6 +219,9 @@ gg2list <- function(p){
217219 name.names <- sprintf(" %s.name" , mark.names )
218220 layer.aes [name.names ] <- layer.aes [mark.names ]
219221 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+ }
220225 }
221226 # # Extract data from built ggplots
222227 built <- ggplot2 :: ggplot_build(p )
@@ -230,10 +235,14 @@ gg2list <- function(p){
230235 df <- built $ data [[i ]]
231236
232237 # # 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).
235244 misc <- list ()
236- for (a in c(" fill" , " colour" )){
245+ for (a in c(" fill" , " colour" , " x " , " y " )){
237246 fun.name <- sprintf(" scale_%s_continuous" , a )
238247 fun <- get(fun.name )
239248 misc $ is.continuous [[a ]] <- tryCatch({
@@ -327,7 +336,11 @@ gg2list <- function(p){
327336 ax.list $ tickfont <- theme2font(tick.text )
328337 title.text <- e(s(" axis.title.%s" ))
329338 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+ }
331344 # # Lines drawn around the plot border:
332345 ax.list $ showline <- ifelse(is.blank(" panel.border" ), FALSE , TRUE )
333346 ax.list $ linecolor <- toRGB(theme.pars $ panel.border $ colour )
@@ -368,7 +381,19 @@ layer2traces <- function(l, d, misc){
368381 data = d )
369382 # # needed for when group, etc. is an expression.
370383 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+ }
372397 # # use un-named parameters so that they will not be exported
373398 # # to JSON as a named object, since that causes problems with
374399 # # e.g. colour.
@@ -455,6 +480,12 @@ layer2traces <- function(l, d, misc){
455480 for (data.i in seq_along(data.list )){
456481 data.params <- data.list [[data.i ]]
457482 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+ }
458489 name.names <- grep(" [.]name$" , names(data.params $ params ), value = TRUE )
459490 if (length(name.names )){
460491 for (a.name in name.names ){
0 commit comments