From 8ae1a20ee8ad997ce64df8f15d1afc6172750f67 Mon Sep 17 00:00:00 2001 From: Toby Dylan Hocking Date: Wed, 23 Apr 2014 17:45:28 -0400 Subject: [PATCH 1/9] test dodge/stack/id bar translation --- inst/tests/test-bar.R | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 inst/tests/test-bar.R diff --git a/inst/tests/test-bar.R b/inst/tests/test-bar.R new file mode 100644 index 0000000000..e95c405c60 --- /dev/null +++ b/inst/tests/test-bar.R @@ -0,0 +1,37 @@ +context("bar") + +researchers <- + data.frame(country=c("Canada", "Canada", "Germany", "USA"), + name=c("Warren", "Andreanne", "Stefan", "Toby"), + papers=c(23, 14, 37, 20), + field=c("Math", "Bio", "Bio", "Math")) + +gg <- ggplot(researchers, aes(country, papers, fill=field)) + +test_that("position_dodge is translated to barmode=group", { + gg.dodge <- gg+geom_bar(stat="identity", position="dodge") + L <- gg2list(gg.dodge) + expect_equal(length(L), 3) + trace.names <- sapply(L[1:2], "[[", "name") + stopifnot(c("Math", "Bio") %in% trace.names) + expect_identical(L$kwargs$layout$barmode, "group") +}) + +test_that("position_stack is translated to barmode=stack", { + gg.stack <- gg+geom_bar(stat="identity", position="stack") + gg2list(gg.stack) + expect_equal(length(L), 3) + trace.names <- sapply(L[1:2], "[[", "name") + stopifnot(c("Math", "Bio") %in% trace.names) + expect_identical(L$kwargs$layout$barmode, "stack") +}) + +test_that("position_identity is translated to barmode=overlay", { + gg.identity <- gg+geom_bar(stat="identity", position="identity") + gg2list(gg.identity) + expect_equal(length(L), 3) + trace.names <- sapply(L[1:2], "[[", "name") + stopifnot(c("Math", "Bio") %in% trace.names) + expect_identical(L$kwargs$layout$barmode, "overlay") +}) + From c5e1594bb13e37a3db5d1f9e88382ce30a4b20dd Mon Sep 17 00:00:00 2001 From: Toby Dylan Hocking Date: Wed, 23 Apr 2014 17:48:57 -0400 Subject: [PATCH 2/9] test-ggplot-bar and expect_true instead of stopifnot --- inst/tests/{test-bar.R => test-ggplot-bar.R} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename inst/tests/{test-bar.R => test-ggplot-bar.R} (87%) diff --git a/inst/tests/test-bar.R b/inst/tests/test-ggplot-bar.R similarity index 87% rename from inst/tests/test-bar.R rename to inst/tests/test-ggplot-bar.R index e95c405c60..b302d5373a 100644 --- a/inst/tests/test-bar.R +++ b/inst/tests/test-ggplot-bar.R @@ -13,7 +13,7 @@ test_that("position_dodge is translated to barmode=group", { L <- gg2list(gg.dodge) expect_equal(length(L), 3) trace.names <- sapply(L[1:2], "[[", "name") - stopifnot(c("Math", "Bio") %in% trace.names) + expect_true(all(c("Math", "Bio") %in% trace.names)) expect_identical(L$kwargs$layout$barmode, "group") }) @@ -22,7 +22,7 @@ test_that("position_stack is translated to barmode=stack", { gg2list(gg.stack) expect_equal(length(L), 3) trace.names <- sapply(L[1:2], "[[", "name") - stopifnot(c("Math", "Bio") %in% trace.names) + expect_true(all(c("Math", "Bio") %in% trace.names)) expect_identical(L$kwargs$layout$barmode, "stack") }) @@ -31,7 +31,7 @@ test_that("position_identity is translated to barmode=overlay", { gg2list(gg.identity) expect_equal(length(L), 3) trace.names <- sapply(L[1:2], "[[", "name") - stopifnot(c("Math", "Bio") %in% trace.names) + expect_true(all(c("Math", "Bio") %in% trace.names)) expect_identical(L$kwargs$layout$barmode, "overlay") }) From c719333322edc04826fa7b391de1131ad7d432ce Mon Sep 17 00:00:00 2001 From: Toby Dylan Hocking Date: Fri, 25 Apr 2014 21:53:29 -0400 Subject: [PATCH 3/9] categorical variables on scatter plot axes --- R/ggplotly.R | 41 ++++++++++++++++++++++++---- inst/tests/test-ggplot-categorical.R | 11 ++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 inst/tests/test-ggplot-categorical.R diff --git a/R/ggplotly.R b/R/ggplotly.R index f705dab93c..4efd0e195e 100644 --- a/R/ggplotly.R +++ b/R/ggplotly.R @@ -199,7 +199,9 @@ gg2list <- function(p){ layout <- list() trace.list <- list() ## Before building the ggplot, we would like to add aes(name) to - ## figure out what the object group is later. + ## figure out what the object group is later. This also copies any + ## needed global aes/data values to each layer, so we do not have to + ## worry about combining global and layer-specific aes/data later. for(layer.i in seq_along(p$layers)){ layer.aes <- p$layers[[layer.i]]$mapping to.copy <- names(p$mapping)[!names(p$mapping) %in% names(layer.aes)] @@ -208,6 +210,9 @@ gg2list <- function(p){ name.names <- sprintf("%s.name", mark.names) layer.aes[name.names] <- layer.aes[mark.names] p$layers[[layer.i]]$mapping <- layer.aes + if(!is.data.frame(p$layers[[layer.i]]$data)){ + p$layers[[layer.i]]$data <- p$data + } } ## Extract data from built ggplots built <- ggplot2::ggplot_build(p) @@ -221,10 +226,14 @@ gg2list <- function(p){ df <- built$data[[i]] ## Test fill and color to see if they encode a quantitative - ## variable. In that case, we do not make traces for separate - ## colors, since there are too many! + ## variable. This may be useful for several reasons: (1) it is + ## sometimes possible to plot several different colors in the same + ## trace (e.g. points), and that is faster for large numbers of + ## data points and colors; (2) factors on x or y axes should be + ## sent to plotly as characters, not as numeric data (which is + ## what ggplot_build gives us). misc <- list() - for(a in c("fill", "colour")){ + for(a in c("fill", "colour", "x", "y")){ fun.name <- sprintf("scale_%s_continuous", a) fun <- get(fun.name) misc$is.continuous[[a]] <- tryCatch({ @@ -318,7 +327,11 @@ gg2list <- function(p){ ax.list$tickfont <- theme2font(tick.text) title.text <- e(s("axis.title.%s")) ax.list$titlefont <- theme2font(title.text) - ax.list$type <- "linear" ## TODO: log scales? + ax.list$type <- if(misc$is.continuous[[xy]]){ + "linear" + }else{## TODO: time scales? + "category" + } ## Lines drawn around the plot border: ax.list$showline <- ifelse(is.blank("panel.border"), FALSE, TRUE) ax.list$linecolor <- toRGB(theme.pars$panel.border$colour) @@ -360,6 +373,18 @@ layer2traces <- function(l, d, misc){ ## needed for when group, etc. is an expression. g$aes <- sapply(l$mapping, function(k) as.character(as.expression(k))) + ## For factors on the axes, we should take the values from the + ## original data. + for(axis.name in c("x", "y")){ + if(!misc$is.continuous[[axis.name]]){ + aes.names <- paste0(axis.name, c("", "end", "min", "max")) + aes.used <- aes.names[aes.names %in% names(g$aes)] + if(length(aes.used)){ + col.used <- g$aes[aes.used] + g$data[aes.used] <- l$data[col.used] + } + } + } ## use un-named parameters so that they will not be exported ## to JSON as a named object, since that causes problems with ## e.g. colour. @@ -446,6 +471,12 @@ layer2traces <- function(l, d, misc){ for(data.i in seq_along(data.list)){ data.params <- data.list[[data.i]] tr <- do.call(getTrace, data.params) + for(v.name in c("x", "y")){ + vals <- tr[[v.name]] + if(is.na(vals[length(vals)])){ + tr[[v.name]] <- vals[-length(vals)] + } + } name.names <- grep("[.]name$", names(data.params$params), value=TRUE) if(length(name.names)){ for(a.name in name.names){ diff --git a/inst/tests/test-ggplot-categorical.R b/inst/tests/test-ggplot-categorical.R new file mode 100644 index 0000000000..704a165b67 --- /dev/null +++ b/inst/tests/test-ggplot-categorical.R @@ -0,0 +1,11 @@ +context("categorical data on the axes") + +d <- head(diamonds, 50) + +test_that("axis type=category when we plot factors", { + gg <- qplot(cut, price, data=d) + info <- gg2list(gg) + l <- info$kwargs$layout + expect_identical(l$xaxis$type, "category") + expect_identical(l$yaxis$type, "linear") +}) From da6443399ff33f2dc9331e22f148379d689239d0 Mon Sep 17 00:00:00 2001 From: Toby Dylan Hocking Date: Fri, 25 Apr 2014 21:56:23 -0400 Subject: [PATCH 4/9] test line colors --- inst/tests/test-ggplot-line.R | 18 ------------- inst/tests/test-ggplot-linetype.R | 42 +++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 18 deletions(-) delete mode 100644 inst/tests/test-ggplot-line.R create mode 100644 inst/tests/test-ggplot-linetype.R diff --git a/inst/tests/test-ggplot-line.R b/inst/tests/test-ggplot-line.R deleted file mode 100644 index a68b58cf24..0000000000 --- a/inst/tests/test-ggplot-line.R +++ /dev/null @@ -1,18 +0,0 @@ -context("linetype") - -test_that("6 different automatic lty converted to plotly's 6 types", { - d <- expand.grid(x=1:6, y=1:6) - gg <- ggplot() + - geom_line(aes(x=x, y=y, group=x, linetype=as.factor(x)), data=d) - expected <- - c("solid", - "dash", - "dot", - "dashdot", - "longdash", - "longdashdot") - info <- gg2list(gg) - generated <- sapply(info[1:6], function(L) L$line$dash) - expect_true(all(generated %in% expected)) - expect_true(all(expected %in% generated)) -}) diff --git a/inst/tests/test-ggplot-linetype.R b/inst/tests/test-ggplot-linetype.R new file mode 100644 index 0000000000..a8ec09f628 --- /dev/null +++ b/inst/tests/test-ggplot-linetype.R @@ -0,0 +1,42 @@ +context("line") + +test_that("6 different automatic lty converted to plotly's 6 types", { + d <- expand.grid(x=1:6, y=1:6) + gg <- ggplot() + + geom_line(aes(x=x, y=y, group=x, linetype=as.factor(x)), data=d) + expected <- + c("solid", + "dash", + "dot", + "dashdot", + "longdash", + "longdashdot") + info <- gg2list(gg) + generated <- sapply(info[1:6], function(L) L$line$dash) + expect_true(all(generated %in% expected)) + expect_true(all(expected %in% generated)) +}) + +test_that("different colored lines become different colored traces", { + ## http://stackoverflow.com/questions/2564258/plot-2-graphs-in-same-plot-in-r/19039094#19039094 + + ## original data in a 'wide' format + x <- seq(-2, 2, 0.05) + y1 <- pnorm(x) + y2 <- pnorm(x, 1, 1) + df <- rbind(data.frame(x, variable="y1", value=y1), + data.frame(x, variable="y2", value=y2)) + ## plot, using the aesthetics argument 'colour' + gg <- ggplot(data = df, aes(x = x, y = value, colour = variable))+ + geom_line()+ + scale_color_manual(values=c(y1="blue", y2="red")) + info <- gg2list(gg) + expect_equal(length(info), 3) + expect_identical(info[[1]]$line$color, toRGB("blue")) + n <- length(x) + expect_identical(info[[1]]$y[1:n], y1) + expect_identical(info[[1]]$x[1:n], x) + expect_identical(info[[2]]$line$color, toRGB("red")) + expect_identical(info[[2]]$y[1:n], y2) + expect_identical(info[[2]]$x[1:n], x) +}) From fe130c67121a410ece2490fec871065475228a0e Mon Sep 17 00:00:00 2001 From: Marianne Corvellec Date: Sun, 27 Apr 2014 18:07:11 -0400 Subject: [PATCH 5/9] This conversion for geom_bar() works but is not complete --- R/ggplotly.R | 56 +++++++++++++++++++++--------------- inst/tests/test-ggplot-bar.R | 2 +- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/R/ggplotly.R b/R/ggplotly.R index f705dab93c..9579611e77 100644 --- a/R/ggplotly.R +++ b/R/ggplotly.R @@ -165,7 +165,16 @@ geom2trace <- L$marker$size <- data$size } L - }) + }, + bar=function(data, params) { + list(x=data$x, + y=data$y, + name=params$name, + text=data$text, + type="bar") + } + ) + #' Convert ggplot2 aes to line parameters. aes2line <- c(linetype="dash", @@ -175,7 +184,8 @@ aes2line <- c(linetype="dash", markLegends <- list(point=c("colour", "fill", "shape"), path=c("linetype", "size", "colour"), - polygon=c("colour", "fill", "linetype", "size", "group")) + polygon=c("colour", "fill", "linetype", "size", "group"), + bar=c("fill")) markUnique <- as.character(unique(unlist(markLegends))) @@ -215,11 +225,11 @@ gg2list <- function(p){ for(i in seq_along(built$plot$layers)){ ## This is the layer from the original ggplot object. L <- p$layers[[i]] - + ## for each layer, there is a correpsonding data.frame which ## evaluates the aesthetic mapping. df <- built$data[[i]] - + ## Test fill and color to see if they encode a quantitative ## variable. In that case, we do not make traces for separate ## colors, since there are too many! @@ -237,7 +247,7 @@ gg2list <- function(p){ FALSE }) } - + ## scales are needed for legend ordering. for(sc in p$scales$scales){ a <- sc$aesthetics @@ -248,10 +258,10 @@ gg2list <- function(p){ misc$breaks[[sc$aesthetics]] <- ranks } } - + ## This extracts essential info for this geom/layer. traces <- layer2traces(L, df, misc) - + ## Do we really need to coord_transform? ##g$data <- ggplot2:::coord_transform(built$plot$coord, g$data, ## built$panel$ranges[[1]]) @@ -263,7 +273,7 @@ gg2list <- function(p){ # grid 0-1 scale). This allows transformations to be used # out of the box, with no additional d3 coding. theme.pars <- ggplot2:::plot_theme(p) - + ## Flip labels if coords are flipped - transform does not take care ## of this. Do this BEFORE checking if it is blank or not, so that ## individual axes can be hidden appropriately, e.g. #1. @@ -329,21 +339,21 @@ gg2list <- function(p){ !is.blank(s("axis.ticks.%s")) layout[[s("%saxis")]] <- ax.list } - + ## Remove legend if theme has no legend position if(theme.pars$legend.position=="none") layout$showlegend <- FALSE - + ## Main plot title. layout$title <- built$plot$labels$title - + ## Background color. layout$plot_bgcolor <- toRGB(theme.pars$panel.background$fill) layout$paper_bgcolor <- toRGB(theme.pars$plot.background$fill) - + ## Legend. layout$margin$r <- 10 layout$legend <- list(bordercolor="transparent", x=100, y=1/2) - + trace.list$kwargs <- list(layout=layout) trace.list } @@ -359,7 +369,7 @@ layer2traces <- function(l, d, misc){ data=d) ## needed for when group, etc. is an expression. g$aes <- sapply(l$mapping, function(k) as.character(as.expression(k))) - + ## use un-named parameters so that they will not be exported ## to JSON as a named object, since that causes problems with ## e.g. colour. @@ -373,25 +383,25 @@ layer2traces <- function(l, d, misc){ ## {"bar":"foo"} names(g$params[[p.name]]) <- NULL } - + ## Convert complex ggplot2 geoms so that they are treated as special ## cases of basic geoms. In ggplot2, this processing is done in the ## draw method of the geoms. - + ## Every plotly trace has one of these types ## type=scatter,bar,box,histogramx,histogram2d,heatmap - + ## for type=scatter, you can define ## mode=none,markers,lines,lines+markers where "lines" is the ## default for 20 or more points, "lines+markers" is the default for ## <20 points. "none" is useful mainly if fill is used to make area ## plots with no lines. - + ## marker=list(size,line,color="rgb(54,144,192)",opacity,symbol) - + ## symbol=circle,square,diamond,cross,x, ## triangle-up,triangle-down,triangle-left,triangle-right - + ## First convert to a "basic" geom, e.g. segments become lines. convert <- toBasic[[g$geom]] basic <- if(is.null(convert)){ @@ -399,7 +409,7 @@ layer2traces <- function(l, d, misc){ }else{ convert(g) } - + ## Then split on visual characteristics that will get different ## legend entries. data.list <- if(basic$geom %in% names(markLegends)){ @@ -407,7 +417,7 @@ layer2traces <- function(l, d, misc){ ## However, continuously colored points are an exception: they do ## not need a legend entry, and they can be efficiently rendered ## using just 1 trace. - + ## Maybe it is nice to show a legend for continuous points? ## if(basic$geom == "point"){ ## to.erase <- names(misc$is.continuous)[misc$is.continuous] @@ -436,7 +446,7 @@ layer2traces <- function(l, d, misc){ data.list <- structure(list(list(data=basic$data, params=basic$params)), names=basic$params$name) } - + getTrace <- geom2trace[[basic$geom]] if(is.null(getTrace)){ stop("conversion not implemented for geom_", diff --git a/inst/tests/test-ggplot-bar.R b/inst/tests/test-ggplot-bar.R index b302d5373a..951022df12 100644 --- a/inst/tests/test-ggplot-bar.R +++ b/inst/tests/test-ggplot-bar.R @@ -9,7 +9,7 @@ researchers <- gg <- ggplot(researchers, aes(country, papers, fill=field)) test_that("position_dodge is translated to barmode=group", { - gg.dodge <- gg+geom_bar(stat="identity", position="dodge") + gg.dodge <- gg + geom_bar(stat="identity", position="dodge") L <- gg2list(gg.dodge) expect_equal(length(L), 3) trace.names <- sapply(L[1:2], "[[", "name") From be24290aa4a368df4e6549a472b546817c640f3f Mon Sep 17 00:00:00 2001 From: Marianne Corvellec Date: Sun, 27 Apr 2014 18:45:28 -0400 Subject: [PATCH 6/9] Small fixes to test --- R/ggplotly.R | 1 - inst/tests/test-ggplot-bar.R | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/R/ggplotly.R b/R/ggplotly.R index 9579611e77..1e4c5159f7 100644 --- a/R/ggplotly.R +++ b/R/ggplotly.R @@ -170,7 +170,6 @@ geom2trace <- list(x=data$x, y=data$y, name=params$name, - text=data$text, type="bar") } ) diff --git a/inst/tests/test-ggplot-bar.R b/inst/tests/test-ggplot-bar.R index 951022df12..ff3bec7b1f 100644 --- a/inst/tests/test-ggplot-bar.R +++ b/inst/tests/test-ggplot-bar.R @@ -18,8 +18,8 @@ test_that("position_dodge is translated to barmode=group", { }) test_that("position_stack is translated to barmode=stack", { - gg.stack <- gg+geom_bar(stat="identity", position="stack") - gg2list(gg.stack) + gg.stack <- gg + geom_bar(stat="identity", position="stack") + L <- gg2list(gg.stack) expect_equal(length(L), 3) trace.names <- sapply(L[1:2], "[[", "name") expect_true(all(c("Math", "Bio") %in% trace.names)) @@ -27,8 +27,8 @@ test_that("position_stack is translated to barmode=stack", { }) test_that("position_identity is translated to barmode=overlay", { - gg.identity <- gg+geom_bar(stat="identity", position="identity") - gg2list(gg.identity) + gg.identity <- gg + geom_bar(stat="identity", position="identity") + L <- gg2list(gg.identity) expect_equal(length(L), 3) trace.names <- sapply(L[1:2], "[[", "name") expect_true(all(c("Math", "Bio") %in% trace.names)) From 50f70b8395f9a47dc90ebabf0aed6cf8970c1585 Mon Sep 17 00:00:00 2001 From: Toby Dylan Hocking Date: Tue, 29 Apr 2014 18:11:08 -0400 Subject: [PATCH 7/9] date conversion --- R/ggplotly.R | 43 ++++++++++++++++++++++------------- inst/tests/test-ggplot-date.R | 17 ++++++++++++++ 2 files changed, 44 insertions(+), 16 deletions(-) create mode 100644 inst/tests/test-ggplot-date.R diff --git a/R/ggplotly.R b/R/ggplotly.R index 4efd0e195e..9067936550 100644 --- a/R/ggplotly.R +++ b/R/ggplotly.R @@ -234,17 +234,20 @@ gg2list <- function(p){ ## what ggplot_build gives us). misc <- list() for(a in c("fill", "colour", "x", "y")){ - fun.name <- sprintf("scale_%s_continuous", a) - fun <- get(fun.name) - misc$is.continuous[[a]] <- tryCatch({ - suppressMessages({ - with.scale <- p+fun() + for(data.type in c("continuous", "date", "datetime", "discrete")){ + fun.name <- sprintf("scale_%s_%s", a, data.type) + misc.name <- paste0("is.", data.type) + misc[[misc.name]][[a]] <- tryCatch({ + fun <- get(fun.name) + suppressMessages({ + with.scale <- p+fun() + }) + ggplot2::ggplot_build(with.scale) + TRUE + }, error=function(e){ + FALSE }) - ggplot2::ggplot_build(with.scale) - TRUE - }, error=function(e){ - FALSE - }) + } } ## scales are needed for legend ordering. @@ -329,8 +332,12 @@ gg2list <- function(p){ ax.list$titlefont <- theme2font(title.text) ax.list$type <- if(misc$is.continuous[[xy]]){ "linear" - }else{## TODO: time scales? + }else if(misc$is.discrete[[xy]]){ "category" + }else if(misc$is.date[[xy]] || misc$is.datetime[[xy]]){ + "date" + }else{ + stop("unrecognized data type for ", xy, " axis") } ## Lines drawn around the plot border: ax.list$showline <- ifelse(is.blank("panel.border"), FALSE, TRUE) @@ -373,15 +380,19 @@ layer2traces <- function(l, d, misc){ ## needed for when group, etc. is an expression. g$aes <- sapply(l$mapping, function(k) as.character(as.expression(k))) - ## For factors on the axes, we should take the values from the - ## original data. + ## For non-numeric data on the axes, we should take the values from + ## the original data. for(axis.name in c("x", "y")){ if(!misc$is.continuous[[axis.name]]){ aes.names <- paste0(axis.name, c("", "end", "min", "max")) aes.used <- aes.names[aes.names %in% names(g$aes)] - if(length(aes.used)){ - col.used <- g$aes[aes.used] - g$data[aes.used] <- l$data[col.used] + for(a in aes.used){ + col.name <- g$aes[aes.used] + data.vec <- l$data[[col.name]] + if(inherits(data.vec, "POSIXt")){ + data.vec <- strftime(data.vec, "%Y-%m-%d %H:%M:%S") + } + g$data[[a]] <- data.vec } } } diff --git a/inst/tests/test-ggplot-date.R b/inst/tests/test-ggplot-date.R new file mode 100644 index 0000000000..9d7a911bf0 --- /dev/null +++ b/inst/tests/test-ggplot-date.R @@ -0,0 +1,17 @@ +context("date") + +test_that("datetimes are converted to e.g. 2013-01-02 05:00:00", { + in.str <- c("17 Mar 1983 06:33:44 AM", + "17 Mar 1984 01:59:55 PM") + time.obj <- strptime(in.str, "%d %b %Y %I:%M:%S %p") + out.str <- strftime(time.obj, "%Y-%m-%d %H:%M:%S") + df <- rbind(data.frame(who="me", time.obj, dollars=c(1.1, 5.6)), + data.frame(who="you", time.obj, dollars=c(10.2, 0))) + gg <- qplot(time.obj, dollars, data=df, color=who, geom="line") + info <- gg2list(gg) + expect_equal(length(info), 3) + expect_identical(info$kwargs$layout$xaxis$type, "date") + for(trace in info[1:2]){ + expect_identical(trace$x, out.str) + } +}) From fc7da4fcf288d6cd17498e23557ba9b6aff0dae2 Mon Sep 17 00:00:00 2001 From: Marianne Corvellec Date: Tue, 6 May 2014 11:59:08 -0400 Subject: [PATCH 8/9] Sketch framework to support barmode conversion --- R/ggplotly.R | 15 +++++++++++++-- inst/tests/test-ggplot-bar.R | 1 - 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/R/ggplotly.R b/R/ggplotly.R index 247e0c8f49..38e81f22ae 100644 --- a/R/ggplotly.R +++ b/R/ggplotly.R @@ -100,6 +100,8 @@ aesConverters <- toRGB(col) },size=identity,alpha=identity,shape=function(pch){ pch2symbol[as.character(pch)] + }, barmode=function(bm) { + position2barmode[bm][[1]] }) toBasic <- @@ -170,7 +172,10 @@ geom2trace <- list(x=data$x, y=data$y, name=params$name, - type="bar") + text=data$text, + type="bar", + # barmode=paramORdefault(...), + fillcolor=toRGB(params$fill)) } ) @@ -184,7 +189,7 @@ markLegends <- list(point=c("colour", "fill", "shape"), path=c("linetype", "size", "colour"), polygon=c("colour", "fill", "linetype", "size", "group"), - bar=c("fill")) + bar=c("fill", "barmode")) markUnique <- as.character(unique(unlist(markLegends))) @@ -373,6 +378,8 @@ gg2list <- function(p){ layout$margin$r <- 10 layout$legend <- list(bordercolor="transparent", x=100, y=1/2) + ## Barmode. + # layout$barmode <- position2barmode[...][[1]] trace.list$kwargs <- list(layout=layout) trace.list } @@ -572,3 +579,7 @@ toRGB <- function(x){ ifelse(is.na(x), "none", rgb.css) } +#' Convert R position to plotly barmode +position2barmode <- c("stack"="stack", + "dodge"="group", + "identity"="overlay") diff --git a/inst/tests/test-ggplot-bar.R b/inst/tests/test-ggplot-bar.R index ff3bec7b1f..a6786f682e 100644 --- a/inst/tests/test-ggplot-bar.R +++ b/inst/tests/test-ggplot-bar.R @@ -34,4 +34,3 @@ test_that("position_identity is translated to barmode=overlay", { expect_true(all(c("Math", "Bio") %in% trace.names)) expect_identical(L$kwargs$layout$barmode, "overlay") }) - From fe929375131ed5584394443e62ec4bb7799fd69b Mon Sep 17 00:00:00 2001 From: Marianne Corvellec Date: Tue, 6 May 2014 19:52:24 -0400 Subject: [PATCH 9/9] Implement conversion from position to barmode --- R/ggplotly.R | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/R/ggplotly.R b/R/ggplotly.R index 38e81f22ae..c7d8a5571e 100644 --- a/R/ggplotly.R +++ b/R/ggplotly.R @@ -100,8 +100,6 @@ aesConverters <- toRGB(col) },size=identity,alpha=identity,shape=function(pch){ pch2symbol[as.character(pch)] - }, barmode=function(bm) { - position2barmode[bm][[1]] }) toBasic <- @@ -174,7 +172,6 @@ geom2trace <- name=params$name, text=data$text, type="bar", - # barmode=paramORdefault(...), fillcolor=toRGB(params$fill)) } ) @@ -189,7 +186,7 @@ markLegends <- list(point=c("colour", "fill", "shape"), path=c("linetype", "size", "colour"), polygon=c("colour", "fill", "linetype", "size", "group"), - bar=c("fill", "barmode")) + bar=c("fill")) markUnique <- as.character(unique(unlist(markLegends))) @@ -227,6 +224,19 @@ gg2list <- function(p){ if(!is.data.frame(p$layers[[layer.i]]$data)){ p$layers[[layer.i]]$data <- p$data } + geom_type <- p$layers[[layer.i]]$geom + geom_type <- strsplit(capture.output(geom_type), "geom_")[[1]][2] + geom_type <- strsplit(geom_type, ": ")[[1]] + ## Barmode. + layout$barmode <- "group" + if (geom_type == "bar") { + pos <- capture.output(p$layers[[layer.i]]$position) + if (length(grep("identity", pos)) > 0) { + layout$barmode <- "overlay" + } else if (length(grep("stack", pos)) > 0) { + layout$barmode <- "stack" + } + } } ## Extract data from built ggplots built <- ggplot2::ggplot_build(p) @@ -378,8 +388,6 @@ gg2list <- function(p){ layout$margin$r <- 10 layout$legend <- list(bordercolor="transparent", x=100, y=1/2) - ## Barmode. - # layout$barmode <- position2barmode[...][[1]] trace.list$kwargs <- list(layout=layout) trace.list }