Powered by AppSignal & Oban Pro

Simple features: ggsf

notebooks/ggsf.livemd

Simple features: ggsf

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_sf(), which covers coord_sf(), geom_sf_label(), geom_sf_text() and stat_sf() too, 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.

These functions draw simple features: sf objects, from R's sf package, tables whose geometry column holds points, lines or polygons. geom_sf() draws whichever of those each row holds, through stat_sf(), and adds coord_sf(), which projects every layer into one coordinate reference system (CRS): the one crs names, or else the first layer's. geom_sf_text() and geom_sf_label() write text at a point on each geometry. Giggly has none of it yet: it has no sf objects, and draws in Cartesian or radial coordinates only.

Counties filled by area

The examples read the counties of North Carolina from a shapefile that comes with the sf package, and run only where that package is installed.

if (requireNamespace("sf", quietly = TRUE)) {
nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
ggplot(nc) +
  geom_sf(aes(fill = AREA))

Not in Giggly yet: sf objects and geom_sf().

Layers in different projections

# If not supplied, coord_sf() will take the CRS from the first layer
# and automatically transform all other layers to use that CRS. This
# ensures that all data will correctly line up
nc_3857 <- sf::st_transform(nc, 3857)
ggplot() +
  geom_sf(data = nc) +
  geom_sf(data = nc_3857, colour = "red", fill = NA)

sf::st_transform() projects the counties into another CRS, Web Mercator (EPSG code 3857), and coord_sf() projects them back into the first layer's, so the red outlines fall on the counties beneath them.

Not in Giggly yet: sf objects, geom_sf(), coord_sf(), and a plot with no data.

Points among polygons

# Unfortunately if you plot other types of feature you'll need to use
# show.legend to tell ggplot2 what type of legend to use
nc_3857$mid <- sf::st_centroid(nc_3857$geometry)
ggplot(nc_3857) +
  geom_sf(colour = "white") +
  geom_sf(aes(geometry = mid, size = AREA), show.legend = "point")

sf::st_centroid() finds the centre of each county, which the second layer draws as a point.

Not in Giggly yet: sf objects, geom_sf() and its show.legend option, and mapping geometry.

Longitude and latitude in other layers

# You can also use layers with x and y aesthetics. To have these interpreted
# as longitude/latitude you need to set the default CRS in coord_sf()
ggplot(nc_3857) +
  geom_sf() +
  annotate("point", x = -80, y = 35, colour = "red", size = 4) +
  coord_sf(default_crs = sf::st_crs(4326))

EPSG code 4326 is longitude and latitude, so the red point is at 80° west, 35° north.

Not in Giggly yet: sf objects, geom_sf(), and coord_sf() and its default_crs option.

Labels

# To add labels, use geom_sf_label().
ggplot(nc_3857[1:3, ]) +
   geom_sf(aes(fill = AREA)) +
   geom_sf_label(aes(label = NAME))
}

Not in Giggly yet: sf objects, and geom_sf() and geom_sf_label().

The world in two projections

These examples need map data from the maps package, and run only where it is installed.

# Thanks to the power of sf, a geom_sf nicely handles varying projections
# setting the aspect ratio correctly.
if (requireNamespace('maps', quietly = TRUE)) {
library(maps)
world1 <- sf::st_as_sf(map('world', plot = FALSE, fill = TRUE))
ggplot() + geom_sf(data = world1)

world2 <- sf::st_transform(
  world1,
  "+proj=laea +y_0=0 +lon_0=155 +lat_0=-90 +ellps=WGS84 +no_defs"
)
ggplot() + geom_sf(data = world2)
}

The second plot projects the world onto a Lambert azimuthal equal-area projection centred on the South Pole.

Not in Giggly yet: map data from the maps package, sf objects, geom_sf(), and a plot with no data.