Skip to content

Commit 8d5df3e

Browse files
authored
Merge pull request #1193 from ropensci/sf-plotly
Non ggplot2 approach to plotting sf objects, addresses #1192
2 parents 5cdf471 + d633adb commit 8d5df3e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1551
-495
lines changed

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ env:
1515
- secure: "WsvmMHN4YVhnk0bLRE04APcLbs5s4vWKSHjEdU0bPXd0xdMTzZeP5D7pxyF1983C+P5LpSnGHv4dgwLMBkNzxJwBR7/Ta7lfO1akYILWwxib+1DVbCqUH5Z4Ba1FSCQptIrLNGR3P7+0Lem4hEhqKdPKltFnxhnXO0Y+MeG71IQ="
1616
# GITHUB_PAT (for pushing to plotly-test-table)
1717
- secure: "Ar5FRxsMJHxb8CQmmsoFx5Tm6ncFvF3LHtAMtfcOE2e9JAbXQ471PGzOMM7yudGa2vVuQJBpB6bWktuE30J68MQxgRmxeaJYmOp+ePqyW80y/zEa2P3R4//eb9Rif2lmsmaqz7HtVfX4xr3YX4N+ZjfyI8TFt5Phue18tXeMoJw="
18+
# MAPBOX_TOKEN (for testing `plot_mapbox()`)
19+
- secure: "QPBEqtLRdwb4ablJORzD0JdCT9ESe3nNdIehM1oxfcNKfpSdf2OFxH3TkeYY1nMpv0mLxiMNTy6xcj9Yk5MaaBCIA0P7q6OdZv9ruzQD1j3g84gP45KwBilbPGjb+/EvOS0fM25vR/pAmA8IyoUfPC2J8HwiNnW8DYdt/hJOJ9A="
1820

1921
# installing Rserve from source requires non-standard R build (--enable-R-shlib)
2022
r_binary_packages:

NAMESPACE

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,10 @@ S3method(print,api)
3939
S3method(print,api_grid)
4040
S3method(print,api_grid_local)
4141
S3method(print,api_plot)
42+
S3method(print,plotly_data)
4243
S3method(rename_,plotly)
4344
S3method(select_,plotly)
4445
S3method(slice_,plotly)
45-
S3method(st_as_plotly,CIRCULARSTRING)
46-
S3method(st_as_plotly,COMPOUNDCURVE)
47-
S3method(st_as_plotly,CURVEPOLYGON)
48-
S3method(st_as_plotly,GEOMETRYCOLLECTION)
49-
S3method(st_as_plotly,LINESTRING)
50-
S3method(st_as_plotly,MULTILINESTRING)
51-
S3method(st_as_plotly,MULTIPOINT)
52-
S3method(st_as_plotly,MULTIPOLYGON)
53-
S3method(st_as_plotly,MULTISURFACE)
54-
S3method(st_as_plotly,POINT)
55-
S3method(st_as_plotly,POLYGON)
5646
S3method(summarise_,plotly)
5747
S3method(to_basic,GeomAbline)
5848
S3method(to_basic,GeomAnnotationMap)
@@ -112,6 +102,7 @@ export(add_polygons)
112102
export(add_ribbons)
113103
export(add_scattergeo)
114104
export(add_segments)
105+
export(add_sf)
115106
export(add_surface)
116107
export(add_text)
117108
export(add_trace)

NEWS.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33
## NEW FEATURES & IMPROVEMENTS
44

55
* Upgraded to plotly.js v1.35.2. A _huge_ amount of features and improvements have been made since v1.29.2 (i.e., the version included in the last CRAN release of the R package - v4.7.1). Highlights include a complete re-write of `scattergl` to make it nearly feature complete with `scatter`, localization of text rendering (i.e., international translations), and two new trace types (`violin` & `table`). Read more about the v1.32.0 release [here](https://codeburst.io/notes-from-the-latest-plotly-js-release-b035a5b43e21) and the complete list of changes [here](https://github.com/plotly/plotly.js/releases).
6-
* The selection mode can now switch from 'transient' to 'persistent' by holding the 'shift' key. It's still possible to _force_ persistent selection by setting `persistent = TRUE` in `highlight()`, but `persistent = FALSE` (the default) is now recommended since it allows one to switch between [persistent/transient selection](https://plotly-book.cpsievert.me/linking-views-without-shiny.html#transient-versus-persistent-selection) in the browser, rather than at the command line.
6+
* Support for **sf** (simple feature) data structures was added to `plot_ly()`, `plot_mapbox()`, and `plot_geo()` (via the new `add_sf()` function). See [this blog post](https://blog.cpsievert.me/2018/02/12/visualizing-geo-spatial-data-with-sf-and-plotly) for an overview.
7+
* New "special arguments" `stroke`, `strokes`, `alpha_stroke`, `span`, and `spans` were added for easier control over the stroke (i.e., outline) appearance of various (filled) graphical marks. For an overview, see the **sf** blog post linked to in the bullet point above.
8+
* The selection (i.e., linked-brushing) mode can now switch from 'transient' to 'persistent' by holding the 'shift' key. It's still possible to _force_ persistent selection by setting `persistent = TRUE` in `highlight()`, but `persistent = FALSE` (the default) is now recommended since it allows one to switch between [persistent/transient selection](https://plotly-book.cpsievert.me/linking-views-without-shiny.html#transient-versus-persistent-selection) in the browser, rather than at the command line.
79
* Instead of an error, `ggplotly(NULL, "message")` and `plotly_build(NULL, "message")` now returns `htmltools::div("message")`, making it easier to relay messages in shiny when data isn't yet ready to plot (see #1116)
810
* The `animation_button()` function gains a `label` argument, making it easier to control the label of an animation button generated through the `frame` API (see #1205).
911

1012
## CHANGES
1113

14+
* The `color` argument now maps to `fillcolor`, making it much easier to use polygon fills to encode data values (e.g., choropleth maps). For backwards-compatibilty reasons, when `color` maps to `fillcolor`, `alpha` defaults to 0.5 (instead of 1). For an example, `plot_mapbox(mn_res, color = ~INDRESNAME)` or `plot_mapbox(mn_res, split = ~INDRESNAME, color = ~AREA, showlegend = FALSE, stroke = I("black"))`.
15+
* The `color` argument no longer automatically add `"markers"` to the `mode` attribute for scatter/scattergl trace types. Those who wish to have the old behavior back, should add `"markers"` to the `mode` explicity (e.g., change `plot_ly(economics, x = ~pce, y = ~pop, color = ~as.numeric(date), mode = "lines")` to `plot_ly(economics, x = ~pce, y = ~pop, color = ~as.numeric(date), mode = "lines+markers")`)
1216
* The `elementId` field is no longer populated, which fixes the "Ignoring explicitly provided widget ID" warning in shiny applications (see #985).
1317

1418
## BUG FIXES

R/add.R

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,60 @@ add_polygons <- function(p, x = NULL, y = NULL, ...,
217217
}
218218

219219

220+
221+
#' @inheritParams add_trace
222+
#' @rdname add_trace
223+
#' @export
224+
#' @examples
225+
#'
226+
#' if (requireNamespace("sf", quietly = TRUE)) {
227+
#' nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
228+
#' plot_ly() %>% add_sf(data = nc)
229+
#' }
230+
add_sf <- function(p, ..., x = ~x, y = ~y, data = NULL, inherit = TRUE) {
231+
dat <- plotly_data(add_data(p, data))
232+
if (!is_sf(dat)) {
233+
stop(
234+
"The `data` for an `add_sf()` layer must be an sf object, ",
235+
"not an object of class: ", class(dat)[1],
236+
call. = FALSE
237+
)
238+
}
239+
if (is_mapbox(p) || is_geo(p)) dat <- st_cast_crs(dat)
240+
bbox <- sf::st_bbox(dat)
241+
set <- attr(dat, "set")
242+
243+
d <- to_basic.GeomSf(dat)
244+
245+
# to_basic() returns either a single data frame or a list of data frames
246+
# (each data frame should be a a collection of the same feature type)
247+
d <- if (is.data.frame(d)) list(d)
248+
249+
# inherit attributes from the "first layer" (except the plotly_eval class)
250+
attrz <- if (inherit) modify_list(unclass(p$x$attrs[[1]]), list(...)) else list(...)
251+
252+
for (i in seq_along(d)) {
253+
# sensible mode/style defaults based on the feature type (e.g. polygon, path, point)
254+
attrs <- modify_list(sf_default_attrs(d[[i]]), attrz)
255+
# scatter3d doesn't currently support fill
256+
if ("z" %in% names(attrs)) attrs$fill <- NULL
257+
args <- list(
258+
p = p,
259+
class = "plotly_sf",
260+
x = x,
261+
y = y,
262+
`_bbox` = bbox,
263+
set = set,
264+
data = if ("group" %in% names(d[[i]])) group_by_(d[[i]], "group", add = TRUE) else d[[i]],
265+
inherit = inherit
266+
)
267+
p <- do.call(add_trace_classed, c(args, attrs))
268+
}
269+
270+
p
271+
}
272+
273+
220274
#' @inheritParams add_trace
221275
#' @rdname add_trace
222276
#' @export

R/coord.R

Lines changed: 0 additions & 66 deletions
This file was deleted.

R/data.R

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,12 @@
2121
#' @format A data frame with three variables: `r`, `t`,
2222
#' `nms`.
2323
"hobbs"
24+
25+
26+
#' Minnesotan Indian Reservation Lands
27+
#'
28+
#' @references \url{https://www.dot.state.mn.us/maps/gdma/gis-data.html}
29+
#'
30+
#' @format An sf data frame with 13 features and 5 fields
31+
#'
32+
"res_mn"

R/ggplotly.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -976,8 +976,8 @@ gg2list <- function(p, width = NULL, height = NULL,
976976
for (i in seq_along(traces)) {
977977
tr <- traces[[i]]
978978
# flipping logic for bar positioning is in geom2trace.GeomBar
979-
if (tr$type != "bar") traces[[i]][c("x", "y")] <- tr[c("y", "x")]
980-
if (tr$type %in% "box") {
979+
if (!identical(tr$type, "bar")) traces[[i]][c("x", "y")] <- tr[c("y", "x")]
980+
if (identical(tr$type, "box")) {
981981
traces[[i]]$orientation <- "h"
982982
traces[[i]]$hoverinfo <- "x"
983983
}

0 commit comments

Comments
 (0)