Maps: geom_map
Mix.install([
{:giggly, path: Path.join(__DIR__, "..")},
{:kino, "~> 0.19"}
])
About this notebook
This notebook follows the examples on ggplot2's reference page for
geom_map(), in the order the page gives
them. Each example shows ggplot2's code first and then Giggly's. An example Giggly cannot draw yet
keeps its ggplot2 code and names what it is waiting for, so the page is also a list of what
remains.
geom_map() draws polygons from a reference map. One table holds the outline of each region and
is given as the layer's map; the plot's data holds the values to show for each region; the
map_id aesthetic links the two. The map is meant as annotation, so it leaves the position scales
alone, and the examples widen them to fit it. geom_map() predates geom_sf() and does not read
sf geometry, though it can be drawn with coord_sf(). Giggly has none of this yet.
Polygons from two tables
# First, a made-up example containing a few polygons, to explain
# how `geom_map()` works. It requires two data frames:
# One contains the coordinates of each polygon (`positions`), and is
# provided via the `map` argument. The other contains the
# values associated with each polygon (`values`). An id
# variable links the two together.
ids <- factor(c("1.1", "2.1", "1.2", "2.2", "1.3", "2.3"))
values <- data.frame(
id = ids,
value = c(3, 3.1, 3.1, 3.2, 3.15, 3.5)
)
positions <- data.frame(
id = rep(ids, each = 4),
x = c(2, 1, 1.1, 2.2, 1, 0, 0.3, 1.1, 2.2, 1.1, 1.2, 2.5, 1.1, 0.3,
0.5, 1.2, 2.5, 1.2, 1.3, 2.7, 1.2, 0.5, 0.6, 1.3),
y = c(-0.5, 0, 1, 0.5, 0, 0.5, 1.5, 1, 0.5, 1, 2.1, 1.7, 1, 1.5,
2.2, 2.1, 1.7, 2.1, 3.2, 2.8, 2.1, 2.2, 3.3, 3.2)
)
ggplot(values) +
geom_map(aes(map_id = id), map = positions) +
expand_limits(positions)
expand_limits(positions) widens the scales to take in the map's coordinates, which geom_map()
leaves out of them.
Not in Giggly yet: geom_map() and expand_limits().
Filling each polygon by its value
ggplot(values, aes(fill = value)) +
geom_map(aes(map_id = id), map = positions) +
expand_limits(positions)
Not in Giggly yet: geom_map() and expand_limits().
Limiting the y axis
ggplot(values, aes(fill = value)) +
geom_map(aes(map_id = id), map = positions) +
expand_limits(positions) + ylim(0, 3)
ylim(0, 3) sets the y axis to run from 0 to 3, a shorter range than the map's.
Not in Giggly yet: geom_map() and expand_limits().
A real map
R's USArrests dataset gives each US state's arrests for murder, assault and rape, and its urban
population; the maps package gives the states' outlines. The vars code turns the table long,
with one row for each state and column, for the last example.
# Now some examples with real maps
if (require(maps)) {
crimes <- data.frame(state = tolower(rownames(USArrests)), USArrests)
# Equivalent to crimes |> tidyr::pivot_longer(Murder:Rape)
vars <- lapply(names(crimes)[-1], function(j) {
data.frame(state = crimes$state, variable = j, value = crimes[[j]])
})
crimes_long <- do.call("rbind", vars)
states_map <- map_data("state")
# without geospatial coordinate system, the resulting plot
# looks weird
ggplot(crimes, aes(map_id = state)) +
geom_map(aes(fill = Murder), map = states_map) +
expand_limits(x = states_map$long, y = states_map$lat)
Not in Giggly yet: geom_map(), expand_limits(), map data from the maps package, and the
USArrests dataset.
A map projection
# in combination with `coord_sf()` we get an appropriate result
ggplot(crimes, aes(map_id = state)) +
geom_map(aes(fill = Murder), map = states_map) +
# crs = 5070 is a Conus Albers projection for North America,
# see: https://epsg.io/5070
# default_crs = 4326 tells coord_sf() that the input map data
# are in longitude-latitude format
coord_sf(
crs = 5070, default_crs = 4326,
xlim = c(-125, -70), ylim = c(25, 52)
)
Not in Giggly yet: geom_map(), coord_sf(), map data from the maps package, and the USArrests
dataset.
A map for each column
ggplot(crimes_long, aes(map_id = state)) +
geom_map(aes(fill = value), map = states_map) +
coord_sf(
crs = 5070, default_crs = 4326,
xlim = c(-125, -70), ylim = c(25, 52)
) +
facet_wrap(~variable)
}
Not in Giggly yet: geom_map(), coord_sf(), map data from the maps package, and the USArrests
dataset. The facets are in Giggly already, as Giggly.Plot.facet_wrap/3.