Skip to content

Commit 296eecb

Browse files
authored
make legend detection code more robust. (#3964)
* make legend detection code more robust. fixes #3963 * properly infer geometry from the right column * add unit test * add news.md
1 parent d3d47be commit 296eecb

File tree

3 files changed

+43
-9
lines changed

3 files changed

+43
-9
lines changed

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# ggplot2 (development version)
22

3+
* Fixed a bug in `geom_sf()` that caused problems with legend-type
4+
autodetection (@clauswilke, #3963).
5+
36
* `annotation_raster()` adds support for native rasters. For large rasters,
47
native rasters render significantly faster than arrays (@kent37, #3388)
58

R/layer-sf.R

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,25 @@ LayerSf <- ggproto("LayerSf", Layer,
4242
(!isTRUE(self$inherit.aes) && is.null(self$mapping$geometry))) {
4343
if (is_sf(data)) {
4444
geometry_col <- attr(data, "sf_column")
45-
self$mapping$geometry <- as.name(geometry_col)
45+
self$mapping$geometry <- sym(geometry_col)
4646
}
4747
}
4848

4949
# automatically determine the legend type
5050
if (is.null(self$legend_key_type)) {
51-
if (is_sf(data)) {
52-
sf_type <- detect_sf_type(data)
53-
if (sf_type == "point") {
54-
self$geom_params$legend <- "point"
55-
} else if (sf_type == "line") {
56-
self$geom_params$legend <- "line"
57-
} else {
58-
self$geom_params$legend <- "polygon"
51+
# first, set default value in case downstream tests fail
52+
self$geom_params$legend <- "polygon"
53+
54+
# now check if the type should not be polygon
55+
if (!is.null(self$mapping$geometry)) {
56+
geometry_column <- as_name(self$mapping$geometry)
57+
if (inherits(data[[geometry_column]], "sfc")) {
58+
sf_type <- detect_sf_type(data[[geometry_column]])
59+
if (sf_type == "point") {
60+
self$geom_params$legend <- "point"
61+
} else if (sf_type == "line") {
62+
self$geom_params$legend <- "line"
63+
}
5964
}
6065
}
6166
} else {

tests/testthat/test-geom-sf.R

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,32 @@ test_that("geom_sf() determines the legend type automatically", {
5252
expect_identical(fun_geom_sf(mpol, "point")$plot$layers[[1]]$geom_params$legend, "point")
5353
})
5454

55+
test_that("geom_sf() determines the legend type from mapped geometry column", {
56+
skip_if_not_installed("sf")
57+
if (packageVersion("sf") < "0.5.3") skip("Need sf 0.5.3")
58+
59+
p1 <- rbind(c(1,1), c(2,2), c(3,3))
60+
s1 <- rbind(c(0,3), c(0,4), c(1,5), c(2,5))
61+
s2 <- rbind(c(0.2,3), c(0.2,4), c(1,4.8), c(2,4.8))
62+
s3 <- rbind(c(0,4.4), c(0.6,5))
63+
64+
d_sf <- sf::st_sf(
65+
g_point = sf::st_sfc(sf::st_multipoint(p1)),
66+
g_line = sf::st_sfc(sf::st_multilinestring(list(s1, s2, s3))),
67+
v = "a"
68+
)
69+
70+
p <- ggplot_build(
71+
ggplot(d_sf) + geom_sf(aes(geometry = g_point, colour = "a"))
72+
)
73+
expect_identical(p$plot$layers[[1]]$geom_params$legend, "point")
74+
75+
p <- ggplot_build(
76+
ggplot(d_sf) + geom_sf(aes(geometry = g_line, colour = "a"))
77+
)
78+
expect_identical(p$plot$layers[[1]]$geom_params$legend, "line")
79+
})
80+
5581
test_that("geom_sf() removes rows containing missing aes", {
5682
skip_if_not_installed("sf")
5783
if (packageVersion("sf") < "0.5.3") skip("Need sf 0.5.3")

0 commit comments

Comments
 (0)