Skip to content

Commit c0eda78

Browse files
authored
Merge pull request #642 from ropensci/docs
Update vignettes
2 parents d2bf2a1 + 5697b17 commit c0eda78

16 files changed

+197
-38
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: plotly
22
Title: Create Interactive Web Graphics via 'plotly.js'
3-
Version: 4.0.0
3+
Version: 4.0.1
44
Authors@R: c(person("Carson", "Sievert", role = c("aut", "cre"),
55
email = "[email protected]"),
66
person("Chris", "Parmer", role = c("aut", "cph"),

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ export(groups)
9292
export(groups.plotly)
9393
export(hide_colorbar)
9494
export(knit_print.plotly_figure)
95+
export(last_plot)
9596
export(layout)
9697
export(mutate)
9798
export(mutate_)

NEWS renamed to NEWS.md

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,29 @@
1-
4.0.0
1+
# 4.0.1 -- 14 June 2016
22

3-
BREAKING CHANGES & IMPROVEMENTS:
3+
## BUG FIXES
44

5-
* 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)
6-
* 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, the `as.widget()` function has been deprecated, and [serialization/memory leak problems](https://github.com/rstudio/shiny/issues/1151) are no longer an issue. This change 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 `?plotly_data` for examples).
5+
* Duplicated values of positional attributes are no longer removed (bug was introduced in v4.0.0).
6+
7+
## OTHER CHANGES
8+
9+
* Upgraded to plotly.js v1.14.2 -- https://github.com/plotly/plotly.js/releases/tag/v1.14.2
10+
11+
# 4.0.0 -- 13 June 2016
12+
13+
## BREAKING CHANGES & IMPROVEMENTS:
14+
15+
* 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()`) since it preserves [referential transparency](https://en.wikipedia.org/wiki/Referential_transparency). For more details, see the [lazyeval vignette](https://github.com/hadley/lazyeval/blob/master/vignettes/lazyeval.Rmd)
16+
* 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, the `last_plot()`/`as.widget()` functions have been deprecated, and [serialization/memory leak problems](https://github.com/rstudio/shiny/issues/1151) are no longer an issue. This change 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 `?plotly_data` for examples).
717
* 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 (see `help(plotly_data)` for examples) instead of the `group` argument (which is now deprecated).
818
* `plot_ly()` now _initializes_ a plotly object (i.e., won't add a scatter trace by default), meaning that something like `plot_ly(x = 1:10, y = 1:10) %>% add_trace(y = 10:1)` creates one trace, instead of two. That being said, if you manually specify a trace type in `plot_ly()`, it will add a layer with that trace type (e.g. `plot_ly(x = 1:10, y = 1:10, type = "scatter") %>% add_trace(y = 10:1)` draws two scatter traces). If no trace type is provided, a sensible type is inferred from the supplied data, and automatically added (i.e., `plot_ly(x = rnorm(100))` now creates a histogram).
919
* 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).
1020
* Aesthetic scaling (e.g., `color`, `symbol`, `size`) is applied at the plot-level, instead of the trace level.
21+
* Size is no longer automatically included in hovertext (closes #549).
1122

12-
NEW FEATURES & IMPROVEMENTS:
23+
## NEW FEATURES & IMPROVEMENTS:
1324

1425
* Added `linetype`/`linetypes` arguments for mapping discrete variables to line types (works very much like the `symbol`/`symbols`).
15-
* Scaling for aesthetics can be avoided via `I()` (closes #428). This is mainly useful for changing default appearance (e.g. `plot_ly(x = 1:10, y = 1:10, color = I(rainbow(10)))`).
26+
* Scaling for aesthetics can be avoided via `I()` (closes #428). This is mainly useful for changing default appearance (e.g. `plot_ly(x = 1:10, y = 1:10, color = I("red"))`).
1627
* Symbols and linetypes now recognize `pch` and `lty` values (e.g. `plot_ly(x = 1:25, y = 1:25, symbol = I(0:24))`)
1728
* A new `alpha` argument controls the alpha transparency of `color` (e.g. `plot_ly(x = 1:10, y = 1:10, color = I("red"), alpha = 0.1)`).
1829
* Added a `sizes` argument for controlling the range of marker size scaling.
@@ -24,7 +35,7 @@ NEW FEATURES & IMPROVEMENTS:
2435
* New `plotly_json()` function for inspecting the data sent to plotly.js (as an R list or JSON).
2536
* `layout()` is now a generic function and uses method dispatch to avoid conflicts with `graphics:layout()` (fixes #464).
2637

27-
OTHER CHANGES:
38+
## OTHER CHANGES:
2839

2940
* Upgraded to plotly.js v1.14.1 -- https://github.com/plotly/plotly.js/releases/tag/v1.14.1
3041

R/deprecated.R

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,15 @@ as.widget <- function(x, ...) {
6666

6767
# for legacy reasons
6868
toWidget <- as.widget
69+
70+
#' Retrive and create the last plotly (or ggplot).
71+
#'
72+
#' This function was deprecated in version 4.0.
73+
#'
74+
#' @param data (optional) a data frame with a class of plotly (and a plotly_hash attribute).
75+
#' @export
76+
77+
last_plot <- function(data = NULL) {
78+
.Deprecated("plot_ly")
79+
data
80+
}

R/plotly_build.R

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ plotly_build.plotly <- function(p) {
9595
# Fortunately, variable mappings don't make much sense with one observation,
9696
# and that is the whole point of "recovering" the built data here, so we just ignore
9797
# cases with one row
98-
isVar <- attrLengths > 1 & attrLengths == nobs & !vapply(trace, is.matrix, logical(1))
98+
isVar <- (attrLengths > 1 & attrLengths == nobs) &
99+
!vapply(trace, is.matrix, logical(1)) &
100+
!vapply(trace, is.bare.list, logical(1))
99101
builtData <- data.frame(trace[isVar], stringsAsFactors = FALSE)
100102

101103
if (NROW(builtData) > 0) {
@@ -181,7 +183,11 @@ plotly_build.plotly <- function(p) {
181183
retrace.first = inherits(x, "plotly_polygon")
182184
)
183185
for (i in x$.plotlyVariableMapping) {
184-
x[[i]] <- structure(uniq(d[[i]]), class = oldClass(x[[i]]))
186+
# try to reduce the amount of data we have to send for non-positional scales
187+
x[[i]] <- structure(
188+
if (i %in% npscales()) uniq(d[[i]]) else d[[i]],
189+
class = oldClass(x[[i]])
190+
)
185191
}
186192
x
187193
})

R/sysdata.rda

14 Bytes
Binary file not shown.

R/utils.R

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ is.colorbar <- function(tr) {
1010
inherits(tr, "plotly_colorbar")
1111
}
1212

13+
is.bare.list <- function(x) {
14+
is.list(x) && !is.data.frame(x)
15+
}
16+
1317
"%||%" <- function(x, y) {
1418
if (length(x) > 0 || is_blank(x)) x else y
1519
}

inst/htmlwidgets/lib/plotlyjs/plotly-latest.min.js

Lines changed: 17 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

inst/htmlwidgets/plotly.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
dependencies:
22
- name: plotlyjs
3-
version: 1.14.1
3+
version: 1.14.2
44
src: "htmlwidgets/lib/plotlyjs"
55
script: plotly-latest.min.js
66
stylesheet: plotly-htmlwidgets.css

man/last_plot.Rd

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat.R

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ skip_on_pull_request <- function() {
7373
# object (aka the data behind the plot).
7474
save_outputs <- function(gg, name) {
7575
print(paste("Running test:", name))
76-
p <- plotly_build(gg)$x
76+
p <- plotly_build(gg)$x[c("data", "layout")]
7777
has_diff <- if (report_diffs) {
7878
# save a hash of the R object
7979
plot_hash <- digest::digest(p)
@@ -84,7 +84,8 @@ save_outputs <- function(gg, name) {
8484
!isTRUE(plot_hash == test_info$hash)
8585
} else FALSE
8686
if (has_diff || build_table) {
87-
pm <- RSeval(conn, "tryCatch(plotly::plotly_build(gg)$x, error = function(e) 'plotly build error')")
87+
RSassign(conn, gg)
88+
pm <- RSeval(conn, "tryCatch(plotly::plotly_build(gg)$x[c('data', 'layout')], error = function(e) e$message)")
8889
if (build_table) {
8990
# save pngs of ggplot
9091
filename <- paste0(gsub("\\s+", "-", name), ".png")

tests/testthat/test-plotly-color.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ test_that("Custom RColorBrewer pallette works for numeric variable", {
6969
})
7070

7171
test_that("axis titles get attached to scene object for 3D plots", {
72-
p <- plot_ly(iris, x = ~Petal.Length, y = ~Petal.Width, z = ~Sepal.Width,
73-
type = "scatter3d", mode = "markers")
72+
p <- plot_ly(iris, x = ~Petal.Length, y = ~Petal.Width, z = ~Sepal.Width)
7473
l <- expect_traces(p, 1, "scatterplot-scatter3d-axes")
74+
expect_identical(l$data[[1]]$type, "scatter3d")
7575
scene <- l$layout$scene
7676
expect_identical(scene$xaxis$title, "Petal.Length")
7777
expect_identical(scene$yaxis$title, "Petal.Width")

tests/testthat/test-plotly-linetype.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ test_that("Mapping a variable to linetype works", {
2222

2323
test_that("Can set the linetype range.", {
2424
p <- plot_ly(tx, x = ~date, y = ~median, linetype = ~city, linetypes = 5:1)
25-
l <- expect_traces(p, 5, "linetype")
25+
l <- expect_traces(p, 5, "linetype2")
2626
lines <- lapply(l$data, "[[", "line")
2727
dashes <- unlist(lapply(lines, "[[", "dash"))
2828
expect_equal(dashes, plotly:::lty2dash(5:1))
2929
})
3030

3131
test_that("Can avoid scaling", {
3232
p <- plot_ly(tx, x = ~date, y = ~median, linetype = I(3))
33-
l <- expect_traces(p, 1, "linetype")
33+
l <- expect_traces(p, 1, "linetype3")
3434
lines <- lapply(l$data, "[[", "line")
3535
dashes <- unlist(lapply(lines, "[[", "dash"))
3636
expect_equal(dashes, plotly:::lty2dash(3))

tests/testthat/test-plotly.R

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ expect_same_data <- function(p1, p2) {
2222
expect_identical(d1, d2)
2323
}
2424

25+
test_that("vector values with repeated values are returned verbatim", {
26+
p <- plot_ly(x = c(1, 2), y = c(1, 1))
27+
l <- plotly_build(p)$x
28+
expect_identical(l$data[[1]]$x, c(1, 2))
29+
expect_identical(l$data[[1]]$y, c(1, 1))
30+
})
31+
2532
test_that("plot_ly defaults to scatterplot", {
2633
p1 <- plot_ly(mtcars, x = ~wt, y = ~mpg)
2734
p2 <- plot_ly(mtcars, x = ~wt, y = ~mpg) %>% add_markers()

vignettes/intro.Rmd

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
---
2-
title: "An overview of plotly's R API"
2+
title: "An intro to `plot_ly()`"
33
author: "Carson Sievert"
4+
date: "`r Sys.Date()`"
45
output:
5-
rmarkdown::html_vignette:
6-
self_contained: false
6+
rmarkdown::html_vignette
77
vignette: >
88
%\VignetteEngine{knitr::rmarkdown}
9-
%\VignetteIndexEntry{Plotly DSL}
9+
%\VignetteIndexEntry{Plotly Intro}
1010
---
1111

1212
```{r, echo = FALSE}
@@ -18,6 +18,53 @@ knitr::opts_chunk$set(
1818
)
1919
```
2020

21+
22+
23+
This vignette outlines the philosophy behind `plot_ly()` through a series of examples (click on the static images to see the interactive version). In a nutshell, `plot_ly()` aims to:
24+
25+
1. Provide sensible defaults/messages/warnings based on the information supplied, but still allows for full customization through [plotly.js](https://github.com/plotly/plotly.js)' (the open source JavaScript graphing library which powers plotly) [figure reference](https://plot.ly/r/reference/).
26+
2. Leverage useful concepts from the grammar of graphics (without requiring it to be used).
27+
28+
## Smart defaults, messages, warnings, errors
29+
30+
If no visualization type is specified, `plot_ly()` infers a sensible type based on the information provided. In this case, a numeric matrix (named `volcano`) is mapped to the `z` attribute, so a heatmap is a sensible default.
31+
32+
```{r, message = TRUE}
33+
library(plotly)
34+
str(volcano)
35+
plot_ly(z = ~volcano)
36+
```
37+
38+
39+
A heatmap is not the only way to visualize a numeric matrix. Since `plot_ly()` only _initializes_ a plotly object,
40+
41+
we can change the default visualization type using any of the `add_*()` functions:
42+
43+
```{r}
44+
add_surface(plot_ly(z = ~volcano))
45+
```
46+
47+
There are a number of `add_*()` functions, for a number
48+
49+
## Functional interface
50+
51+
Plotly's R package has a functional interface: every function takes a plotly object as it's first input argument and returns a modified plotly object. To make code more readable, plotly re-exports the pipe operator (`%>%`) from the magrittr package. The pipe operator takes the object on the left-hand side and injects it into the first argument (by default) of the function on the right-hand side. This allows us to read code from left to right instead of inside out.
52+
53+
```{r, eval = FALSE}
54+
# these two lines of code are equivalent, but the second is easier to read
55+
plotly_POST(add_surface(plot_ly(z = ~volcano)))
56+
plot_ly(z = ~volcano) %>% add_surface() %>% plotly_POST()
57+
```
58+
59+
60+
61+
62+
```{r}
63+
plot_ly(diamonds, x = ~cut)
64+
plot_ly(diamonds, y = ~cut)
65+
```
66+
67+
2168
To create a plotly visualization, start with `plot_ly()`.
2269

2370
```{r}

vignettes/overview.Rmd

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
---
2+
title: "plotly overview"
3+
author: "Carson Sievert"
4+
date: "`r Sys.Date()`"
5+
output:
6+
rmarkdown::html_vignette:
7+
self_contained: false
8+
vignette: >
9+
%\VignetteEngine{knitr::rmarkdown}
10+
%\VignetteIndexEntry{Plotly Intro}
11+
---
12+
13+
```{r, echo = FALSE}
14+
knitr::opts_chunk$set(
15+
message = FALSE,
16+
warning = FALSE,
17+
fig.width = 7,
18+
fig.height = 3
19+
)
20+
```
21+
22+
plotly is an R package for making interactive graphics via the open source JavaScript graphing library [plotly.js](https://github.com/plotly/plotly.js). It provides two main ways to create a plotly visualization: `ggplotly()` and `plot_ly()`. Both of these functions output an [htmlwidget](http://www.htmlwidgets.org/) object, which allows plots to work seamlessly and consistently across various contexts (e.g., R Markdown documents, shiny apps, inside RStudio, or any other R command prompt). For IPython/Jupyter notebook users, there is also an `embed_notebook()` function to embed plots as iframes pointing to a local HTML file. For [plot.ly](https://plot.ly/) subscribers, there is a `plotly_POST()` function for sending local graphs to your account, and a `get_figure()` function for downloading publicly hosted plot.ly figure(s).
23+
24+
## Translate ggplot2 to plotly with `ggplotly()`
25+
26+
The `ggplotly()` function translates [ggplot2](https://cran.r-project.org/web/packages/ggplot2/index.html) graphics to a plotly equivalent, for example:
27+
28+
```{r}
29+
library(plotly)
30+
p <- ggplot(txhousing, aes(x = date, y = median, group = city)) +
31+
geom_line(alpha = 0.3) +
32+
geom_line(data = subset(txhousing, city == "Houston"), color = "red")
33+
ggplotly(p)
34+
```
35+
36+
If you know ggplot2, `ggplotly()` is great since you can add some interactivity (specifically, idenfication + zoom & pan) to your plots for free. Also,
37+
38+
The `ggplotly()` function tries its best to replicate what you see _exactly_ in the static ggplot2 graph.
39+
40+
The output of a `ggplotly()` function is a plotly object.
41+
42+
## The `plot_ly()` interface
43+
44+
The `plot_ly()` function draws inspiration from ggplot2's implementation of the grammar of graphics, but provides a more flexible and direct interface to [plotly.js](https://github.com/plotly/plotly.js). The interface is also functional, and designed to work with dplyr, so visualization can be described as a sequence of data manipulations and visual components via the pipe operator (`%>%`) from the magrittr package.
45+
46+
```{r}
47+
txhousing %>%
48+
group_by(city) %>%
49+
plot_ly(x = ~date, y = ~median) %>%
50+
add_lines(alpha = 0.3, color = I("black"), name = "Texan Cities") %>%
51+
filter(city == "Houston") %>%
52+
add_lines(color = I("red"), name = "Houston")
53+
```
54+
55+
TODO: list resources

0 commit comments

Comments
 (0)