Skip to content

Commit 3b2b41e

Browse files
committed
Merge updates
2 parents be24290 + da64433 commit 3b2b41e

File tree

4 files changed

+90
-24
lines changed

4 files changed

+90
-24
lines changed

R/ggplotly.R

+37-6
Original file line numberDiff line numberDiff line change
@@ -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){

inst/tests/test-ggplot-categorical.R

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
context("categorical data on the axes")
2+
3+
d <- head(diamonds, 50)
4+
5+
test_that("axis type=category when we plot factors", {
6+
gg <- qplot(cut, price, data=d)
7+
info <- gg2list(gg)
8+
l <- info$kwargs$layout
9+
expect_identical(l$xaxis$type, "category")
10+
expect_identical(l$yaxis$type, "linear")
11+
})

inst/tests/test-ggplot-line.R

-18
This file was deleted.

inst/tests/test-ggplot-linetype.R

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
context("line")
2+
3+
test_that("6 different automatic lty converted to plotly's 6 types", {
4+
d <- expand.grid(x=1:6, y=1:6)
5+
gg <- ggplot() +
6+
geom_line(aes(x=x, y=y, group=x, linetype=as.factor(x)), data=d)
7+
expected <-
8+
c("solid",
9+
"dash",
10+
"dot",
11+
"dashdot",
12+
"longdash",
13+
"longdashdot")
14+
info <- gg2list(gg)
15+
generated <- sapply(info[1:6], function(L) L$line$dash)
16+
expect_true(all(generated %in% expected))
17+
expect_true(all(expected %in% generated))
18+
})
19+
20+
test_that("different colored lines become different colored traces", {
21+
## http://stackoverflow.com/questions/2564258/plot-2-graphs-in-same-plot-in-r/19039094#19039094
22+
23+
## original data in a 'wide' format
24+
x <- seq(-2, 2, 0.05)
25+
y1 <- pnorm(x)
26+
y2 <- pnorm(x, 1, 1)
27+
df <- rbind(data.frame(x, variable="y1", value=y1),
28+
data.frame(x, variable="y2", value=y2))
29+
## plot, using the aesthetics argument 'colour'
30+
gg <- ggplot(data = df, aes(x = x, y = value, colour = variable))+
31+
geom_line()+
32+
scale_color_manual(values=c(y1="blue", y2="red"))
33+
info <- gg2list(gg)
34+
expect_equal(length(info), 3)
35+
expect_identical(info[[1]]$line$color, toRGB("blue"))
36+
n <- length(x)
37+
expect_identical(info[[1]]$y[1:n], y1)
38+
expect_identical(info[[1]]$x[1:n], x)
39+
expect_identical(info[[2]]$line$color, toRGB("red"))
40+
expect_identical(info[[2]]$y[1:n], y2)
41+
expect_identical(info[[2]]$x[1:n], x)
42+
})

0 commit comments

Comments
 (0)