Skip to content

Major update to plot_ly() #628

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 75 commits into from
Jul 13, 2016
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
f30c06d
rethink evaluation and plotly object representation model
cpsievert May 26, 2016
c1c0ec9
make group2NA simpler and reusable
cpsievert May 26, 2016
d9c479d
fixes for style(), group2NA(), import dplyr
cpsievert May 27, 2016
ba0aa50
dplyrify group2NA (now much, much faster)
cpsievert May 27, 2016
6bce1b8
first implementation of dplyr methods (thanks ggvis)
cpsievert May 27, 2016
9409c14
ggplotly should return information about the data so it works with do…
cpsievert May 27, 2016
3d10149
deprecate group argument in favor of group_by()
cpsievert May 31, 2016
becb122
always inherit arguments from plot_ly()
cpsievert Jun 1, 2016
bb83979
error checking for trace attributes
cpsievert Jun 1, 2016
7300e8d
unlink file when updating plotlyjs attrs
cpsievert Jun 9, 2016
f8729c1
merge conflicts
cpsievert Jun 9, 2016
5a4b314
fix NEWS version
cpsievert Jun 9, 2016
578bb2a
modify tests to reflect backwards-incompatible changes
cpsievert Jun 10, 2016
b546d10
if trace type is missing in add_*(), inherit from first trace
cpsievert Jun 10, 2016
03da3d4
use viridisLite; start thinking about 'transforms'
cpsievert Jun 10, 2016
94a8797
update intro vignette
cpsievert Jun 10, 2016
627ead9
aesthetic mappings should be plot (not trace) specific; add linetype/…
cpsievert Jun 15, 2016
3a9ae7a
fix trace layering logic; avoid hard-coding data_array boxing logic
cpsievert Jun 15, 2016
bdc27d1
Use rapply to evaluate formulas of arbitrary depth
cpsievert Jun 16, 2016
7688a57
export group_by
cpsievert Jun 16, 2016
ed1e4fc
various bug fixes; updates to docs/tests
cpsievert Jun 16, 2016
5e3f011
more documentation
cpsievert Jun 16, 2016
f94645c
trace type inference
cpsievert Jun 17, 2016
ea7e097
better docs; plotly_spec -> plotly_json; bug fixes
cpsievert Jun 17, 2016
c002991
fix layout bug identified by @timelyportfolio
cpsievert Jun 17, 2016
dc2669b
for consistency in naming; add_points -> add_markers
cpsievert Jun 17, 2016
823e1ba
implement size/sizes; fix symbols; better docs
cpsievert Jun 17, 2016
b4d482d
fix NAMESPACE
cpsievert Jun 17, 2016
f201bcc
remove redundant R/dplyr.R
cpsievert Jun 20, 2016
653a584
fix grouping within multiple traces; fix axis titles; fix hovermode d…
cpsievert Jun 20, 2016
2d3f368
fix has_attr
cpsievert Jun 20, 2016
ec48625
fix uniq
cpsievert Jun 20, 2016
3d618ba
improve group2NA; fix zcolor bugs; improve tests
cpsievert Jun 20, 2016
7eafaa7
update subplot vignette; safer data referencing
cpsievert Jun 20, 2016
a63ff71
import/namespace updates
cpsievert Jun 20, 2016
d23ff3c
travis tests no longer need envir hacks
cpsievert Jun 20, 2016
d025989
fixes for plotly figures; don't document group2NA
cpsievert Jun 20, 2016
b12f507
fix problems identified by R CMD check
cpsievert Jun 20, 2016
d724e59
let the travis fun begin
cpsievert Jun 20, 2016
2578156
get add_polygon working
cpsievert Jun 20, 2016
445b9af
get add_lines() working
cpsievert Jun 20, 2016
6410831
maybe caching is the problem
cpsievert Jun 21, 2016
a5600a7
GGally
cpsievert Jun 21, 2016
57a9b71
are we having fun yet?
cpsievert Jun 21, 2016
254422c
I give up
cpsievert Jun 21, 2016
d6aeeec
more transform/group fixes; deparsed axis titles should only be set w…
cpsievert Jun 21, 2016
6a59af2
fix some special cases in color mapping
cpsievert Jun 21, 2016
14abd2a
make hide_colorbar more universal; don't require formulas for variabl…
cpsievert Jun 21, 2016
c48c5ae
better 3d/z color mapping
cpsievert Jun 21, 2016
09a03d4
go back to caching
cpsievert Jun 21, 2016
066b12d
get add_area()/add_ribbon() working; place all add_*() functions on ?…
cpsievert Jun 22, 2016
22d180a
fix NAMESPACING
cpsievert Jun 22, 2016
0ed2271
you have to pass the arguments through silly
cpsievert Jun 22, 2016
7a1254e
add add_segments()
cpsievert Jun 22, 2016
86c41f7
improve toWebGl implementation; safer group var naming
cpsievert Jun 22, 2016
abc39dd
deprecate as.widget
cpsievert Jun 22, 2016
268d5c4
update NEWS; better deparsing
cpsievert Jun 22, 2016
456d186
add event source; fixes event_data() on plotly graphs
cpsievert Jun 22, 2016
b2b9bd7
fix config()
cpsievert Jun 22, 2016
04dde5d
update inst/examples
cpsievert Jun 22, 2016
132b9cd
vapply is too strict
cpsievert Jun 22, 2016
3335d39
documentation fixes
cpsievert Jun 22, 2016
fd2d9d5
some grouping/ordering fixes
cpsievert Jun 23, 2016
0e744dc
add_heatmap
cpsievert Jun 23, 2016
a807ad4
add a few more basic add_*() functions
cpsievert Jun 23, 2016
1359a14
moar add_*()
cpsievert Jun 23, 2016
e967669
symbol/linetype fixes
cpsievert Jun 24, 2016
ced729f
fix return value of lmgadget
cpsievert Jun 24, 2016
b16f8b7
better plotly_data() examples; use @rawNamespace to avoid unwanted S3…
cpsievert Jun 26, 2016
522224c
export filter
cpsievert Jun 28, 2016
3e3e881
a few half-baked ideas for fill/stroke/alpha shortcuts
cpsievert Jun 29, 2016
77d47ed
upgrade to plotlyjs 1.14.1
cpsievert Jul 6, 2016
d705371
provide scaling escape hatch via I(); add alpha argument; get missing…
cpsievert Jul 13, 2016
1bd9d6a
fix bad example
cpsievert Jul 13, 2016
63e0ddb
curse you cbind
cpsievert Jul 13, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: plotly
Title: Create Interactive Web Graphics via 'plotly.js'
Version: 3.6.5
Version: 4.0.0
Authors@R: c(person("Carson", "Sievert", role = c("aut", "cre"),
email = "[email protected]"),
person("Chris", "Parmer", role = c("aut", "cph"),
Expand All @@ -27,13 +27,13 @@ Imports:
jsonlite,
magrittr,
digest,
viridis,
viridisLite,
base64enc,
htmlwidgets,
tidyr,
dplyr,
hexbin
Suggests:
dplyr,
maps,
ggthemes,
GGally,
Expand All @@ -47,7 +47,8 @@ Suggests:
RColorBrewer,
Rserve,
RSclient,
broom
broom,
webshot
LazyData: true
VignetteBuilder: knitr
RoxygenNote: 5.0.1
54 changes: 43 additions & 11 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Generated by roxygen2: do not edit by hand

S3method(arrange_,plotly)
S3method(distinct_,plotly)
S3method(geom2trace,GeomBar)
S3method(geom2trace,GeomBlank)
S3method(geom2trace,GeomBoxplot)
Expand All @@ -13,14 +15,13 @@ S3method(geom2trace,GeomTile)
S3method(geom2trace,default)
S3method(ggplotly,ggmatrix)
S3method(ggplotly,ggplot)
S3method(plotly_build,default)
S3method(group_by_,plotly)
S3method(layout,matrix)
S3method(layout,plotly)
S3method(plotly_build,gg)
S3method(plotly_build,plotly_built)
S3method(plotly_build,plotly_hash)
S3method(plotly_build,plotly_subplot)
S3method(print,figure)
S3method(print,plotly_built)
S3method(print,plotly_hash)
S3method(plotly_build,list)
S3method(plotly_build,plotly)
S3method(print,plotly_figure)
S3method(to_basic,GeomAbline)
S3method(to_basic,GeomArea)
S3method(to_basic,GeomBoxplot)
Expand All @@ -47,38 +48,65 @@ S3method(to_basic,GeomViolin)
S3method(to_basic,GeomVline)
S3method(to_basic,default)
export("%>%")
export(add_data)
export(add_lines)
export(add_points)
export(add_polygons)
export(add_ribbons)
export(add_text)
export(add_trace)
export(as.widget)
export(config)
export(embed_notebook)
export(event_data)
export(explain_attrs)
export(export)
export(filter_.plotly)
export(geom2trace)
export(get_figure)
export(gg2list)
export(ggplotly)
export(knit_print.figure)
export(knit_print.plotly_built)
export(knit_print.plotly_hash)
export(last_plot)
export(group_by)
export(groups.plotly)
export(knit_print.plotly_figure)
export(layout)
export(mutate_.plotly)
export(offline)
export(plot_ly)
export(plotly)
export(plotlyOutput)
export(plotly_IMAGE)
export(plotly_POST)
export(plotly_build)
export(plotly_data)
export(plotly_empty)
export(plotly_json)
export(plotly_spec)
export(rename_.plotly)
export(renderPlotly)
export(schema)
export(select_.plotly)
export(signup)
export(slice_.plotly)
export(style)
export(subplot)
export(summarise_.plotly)
export(toRGB)
export(toWebGL)
export(to_basic)
export(transmute_.plotly)
export(ungroup.plotly)
import(ggplot2)
importFrom(base64enc,base64encode)
importFrom(dplyr,arrange_)
importFrom(dplyr,distinct_)
importFrom(dplyr,do)
importFrom(dplyr,group_by)
importFrom(dplyr,group_by_)
importFrom(grDevices,col2rgb)
importFrom(graphics,layout)
importFrom(htmlwidgets,createWidget)
importFrom(htmlwidgets,saveWidget)
importFrom(htmlwidgets,shinyRenderWidget)
importFrom(htmlwidgets,shinyWidgetOutput)
importFrom(htmlwidgets,sizingPolicy)
Expand All @@ -91,10 +119,14 @@ importFrom(httr,content)
importFrom(httr,stop_for_status)
importFrom(jsonlite,fromJSON)
importFrom(jsonlite,toJSON)
importFrom(lazyeval,dots_capture)
importFrom(lazyeval,f_eval)
importFrom(lazyeval,f_list)
importFrom(magrittr,"%>%")
importFrom(stats,complete.cases)
importFrom(stats,setNames)
importFrom(tidyr,gather)
importFrom(tidyr,unnest)
importFrom(utils,browseURL)
importFrom(utils,data)
importFrom(utils,getFromNamespace)
Expand Down
26 changes: 25 additions & 1 deletion NEWS
Original file line number Diff line number Diff line change
@@ -1,4 +1,28 @@
3.6.4 -- 31 May 2016
4.0.0

BREAKING CHANGES & IMPROVEMENTS:

* Formulas (instead of plain expressions) are now required when using variable mappings. For example, `plot_ly(mtcars, x = wt, y = mpg, color = vs)` should now be `plot_ly(mtcars, x = ~wt, y = ~mpg, color = ~vs)`. This is a major breaking change, but it is necessary to ensure that evaluation is correct in all contexts (as a result, `evaluate` argument is now deprecated as it is no longer needed). It also has the benefit of being easier to program with (i.e., writing your own custom functions that wrap `plot_ly()`). For more details, see the [lazyeval vignette](https://github.com/hadley/lazyeval/blob/master/vignettes/lazyeval.Rmd)
* The data structure used to represent plotly objects is now an htmlwidget object (instead of a data frame with a special attribute tracking visual mappings). As a result, plotly objects can now be serialized across R sessions and avoid [memory leak issues](https://github.com/rstudio/shiny/issues/1151). This also implies that arbitrary data manipulation functions can no longer be intermingled inside a plot pipeline, but plotly methods for dplyr's data manipulation verbs are now provided (see `help("plotly-data")` for more details).
* The `group` variable mapping no longer create multiple traces, but instead defines "gaps" within a trace (fixes #418, #381, #577). Groupings should be declared via the new `group_by()` function (for examples, see `help("plotly-data")`) instead of the `group` argument (which is now deprecated).
* Scales for variable mappings (such as `color`, `symbol`, `linetype`) are now applied at the plot-level instead of the trace level. As a result, the `colors`/`symbols` arguments have been removed from `add_trace()`.
* The `inherit` argument is deprecated. Any arguments/attributes specified in `plot_ly()` will automatically be passed along to additional traces added via `add_trace()` (or any of it's `add_*()` siblings).

NEW FEATURES & IMPROVEMENTS:

* Error checking for trace and layout attributes.
* Added `linetype`/`linetypes` arguments for mapping discrete variables to line types (this works very much like the `symbol`/`symbols`).
* New `add_points()`/`add_lines()`/`add_text()`/`add_polygon`/`add_ribbon()` functions provide a shorthand for common plots.
* New `toWebGL()` function for easy conversion from SVG to WebGL.
* New `export()` function makes it easy to save plots as png/jpeg/pdf (fixes #311).
* `layout()` is now a generic function and uses method dispatch to avoid conflicts with `graphics:layout()` (fixes #464).
* Added a `plotly_spec()` function for inspecting the data sent to plotly.js (as an R list or JSON).

OTHER CHANGES:

* Upgraded to plotly.js v1.13.0 -- https://github.com/plotly/plotly.js/releases/tag/v1.13.0

3.6.5 -- 10 June 2016

IMPROVEMENT:

Expand Down
169 changes: 169 additions & 0 deletions R/add.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#' Add data to a plotly visualization
#'
#' @param p a plotly visualization
#' @param data a data frame.
#' @export
#' @examples
#'
#' NULL %>% plot_ly() %>% add_data(economics) %>% add_trace(x = ~date, y = ~pce)
add_data <- function(p, data = NULL) {
if (is.null(data)) return(p)
if (!is.plotly(p)) {
stop("Don't know how to add traces to an object of class: ",
class(p), call. = FALSE)
}
id <- new_id()
p$x$visdat[[id]] <- function() data
p$x$cur_data <- id
# TODO: should this also override the data used for the most recent trace?
p
}

#' Add trace(s) to a plotly visualization
#'
#' @param p a plotly or ggplot object.
#' @param ... These arguments are documented in the references section below.
#' Note that acceptable arguments depend on the trace type.
#' @param color Either a variable name or a vector to use for color mapping.
#' @param symbol Either a variable name or a (discrete) vector to use for symbol encoding.
#' @param size A variable name or numeric vector to encode the size of markers.
#' @param linetype Either a variable name or a (discrete) vector to use for linetype encoding.
#' @param data A data frame to associate with this trace (optional). If not
#' provided, arguments are evaluated using the data frame in \code{\link{plot_ly}()}.
#' @seealso \code{\link{plot_ly}()}
#' @references \url{https://plot.ly/r/reference/}
#' @author Carson Sievert
#' @export
#' @examples
#'
#' p <- plot_ly(economics, x = ~date, y = ~uempmed)
#' p
#' p %>% add_points()
#' p %>% add_lines()
#' p %>% add_text(text = ".")
#'
#' # attributes declared in plot_ly() carry over to downstream traces
#' plot_ly(economics, x = ~date, y = ~uempmed) %>%
#' add_points(color = ~pop) %>%
#' add_lines(line = list(color = "red"))
#'
#'
add_trace <- function(p, ...,
color, symbol, size, linetype, data = NULL) {
# "native" plotly arguments
attrs <- list(...)

# tack on "special" arguments
attrs$color <- verify_arg(color)
attrs$symbol <- verify_arg(symbol)
attrs$size <- verify_arg(size)

attrs$colors <- colors
attrs$symbols <- symbols

if (!is.null(attrs[["group"]])) {
warning("The group argument has been deprecated. Use group_by() instead.")
}

p <- add_data(p, data)

# inherit attributes from the "first layer"
new_attrs <- modify_list(p$x$attrs[[1]], attrs)

p$x$attrs <- c(
p$x$attrs %||% list(),
setNames(list(new_attrs), p$x$cur_data)
)

p
}

#' Add points to a plotly vis
#'
#' @export
add_points <- function(p, ...) {
add_trace(p, type = "scatter", mode = "markers", ...)
}

#' Add lines to a plotly vis
#'
#' @export
add_lines <- function(p, ...) {
add_trace(p, type = "scatter", mode = "lines", ...)
}

#' Add text to a plotly vis
#'
#' @export
add_text <- function(p, ...) {
# TODO: throw error if no text attribute is found
add_trace(p, type = "scatter", mode = "text", ...)
}

#' Add polygons to a plotly vis
#'
#' @export
#' @examples
#'
#' library(dplyr)
#' data(canada.cities, package = "maps")
#'
#' ggplot2::map_data("world", "canada") %>%
#' group_by(group) %>%
#' plot_ly(x = ~long, y = ~lat, hoverinfo = "none") %>%
#' add_points(text = ~paste(name, "<br />", pop), hoverinfo = "text",
#' data = canada.cities) %>%
#' layout(showlegend = FALSE)
add_polygons <- function(p, ...) {
# TODO: Should mode='markers+lines'? If so, retrace first points?
add_trace(p, type = "scatter", mode = "lines", fill = "toself", ...)
}

#' Add ribbons to a plotly vis
#'
#' Ribbons are a special case of polygons.
#'
#' @export
add_ribbons <- function(p, ...) {
# TODO: add ymin, ymax arguments?
add_polygons(...)
}


# #'
# #'
# #' @export
# #' @examples
# #'
# #' x <- rnorm(10)
# #' plot_ly(x = ~x) %>%
# #' add_chull()
# add_chull <- function(p, ...) {
# stop("not yet implemented")
# ch <- chull(x, y = NULL)
# # TODO: Should mode='markers+lines'? If so, retrace first points?
# add_polygons(...)
# }


## ------------------------------------------------------------------------
## Non-trace addition
## ------------------------------------------------------------------------
#
##' @export
#add_transform <- function(p, ...) {
# stop("not yet implemented")
#}
#
#
##' @export
#add_shape <- function(p, ...) {
# stop("not yet implemented")
#}
#
##' @export
#add_annotation <- function(p, ...) {
# stop("not yet implemented")
#}


43 changes: 43 additions & 0 deletions R/debug.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#' Obtain JSON sent to plotly.js
#'
#' This function returns the JSON sent to plotly.js which can be useful for
#' debugging.
#'
#' @param p a plotly or ggplot object.
#' @param ... other options passed onto \code{listviewer::jsonedit}
#' @export
#' @examples
#'
#' plotly_spec(plot_ly())

plotly_spec <- function(p = plot_ly(), ...) {
if (system.file(package = "listviewer") == "") {
stop("This function requires the listviewer package:\n",
"install.packages('listviewer')", call. = FALSE)
}
listviewer::jsonedit(to_JSON(plotly_build(p)$x), mode = "form", ...)
}


#' Display plot schema
#'
#' @export
#' @examples
#'
#' schema()

schema <- function() {
listviewer::jsonedit(Schema, mode = "form")
}

#' Show information about attribute(s) of a given trace type
#'
#' @export
#' @param type a trace type
#' @param attrs attributes for the race type
#' @examples
#'
#' explain_attrs()
explain_attrs <- function(type = "scatter", attrs = c("x", "y")) {
jsonlite::toJSON(verify_attrs(type, attrs), pretty = TRUE)
}
Loading