-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathgeom-map.R
98 lines (87 loc) · 2.72 KB
/
geom-map.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#' @include geom-polygon.R
NULL
#' @rdname geom-docs
#' @export
geom_map_pattern <- function(mapping = NULL, data = NULL,
stat = "identity",
...,
map,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE) {
# Get map input into correct form
stopifnot(is.data.frame(map))
if (!is.null(map$lat)) map$y <- map$lat
if (!is.null(map$long)) map$x <- map$long
if (!is.null(map$region)) map$id <- map$region
if (!all(c("x", "y", "id") %in% names(map))) {
cli::cli_abort("{.arg map} must have the columns {.col x}, {.col y}, and {.col id}.")
}
layer(
data = data,
mapping = mapping,
stat = stat,
geom = GeomMapPattern,
position = PositionIdentity,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list2(
map = map,
na.rm = na.rm,
...
)
)
}
#' @rdname ggpattern-ggproto
#' @format NULL
#' @usage NULL
#' @export
GeomMapPattern <- ggproto("GeomMapPattern", GeomPolygonPattern,
draw_panel = function(data, panel_params, coord, lineend = "butt",
linejoin = "round", linemitre = 10, map) {
# Only use matching data and map ids
common <- intersect(data$map_id, map$id)
data <- data[data$map_id %in% common, , drop = FALSE]
map <- map[map$id %in% common, , drop = FALSE]
# Munch, then set up id variable for polygonGrob -
# must be sequential integers
coords <- coord_munch(coord, map, panel_params, is_closed = TRUE)
coords$group <- coords$group %||% coords$id
grob_id <- match(coords$group, unique0(coords$group))
# Align data with map
data_rows <- match(coords$id[!duplicated(grob_id)], data$map_id)
data <- data[data_rows, , drop = FALSE]
polygons <- split(coords, coords$group)
boundary_dfs <- lapply(polygons, function(polygon) {
create_polygon_df(
x = polygon$x,
y = polygon$y
)
})
pattern_grobs <- create_pattern_grobs(data, boundary_dfs)
col <- data$colour
fill <- fill_alpha(data$fill, data$alpha)
lwd <- data$linewidth * .pt
polygon_grob_fn <- function(col, fill, lwd) {
polygonGrob(
x = coords$x,
y = coords$y,
default.units = "native",
id = grob_id,
gp = gpar(col = col,
fill = fill,
lwd = lwd,
lineend = lineend,
linejoin = linejoin,
linemitre = linemitre
)
)
}
grobTree(
polygon_grob_fn(NA, fill, 0),
pattern_grobs,
polygon_grob_fn(col, NA, lwd)
)
},
required_aes = c("map_id")
)