rr-sfcentroid

st_centroid renders all labels on the same point


I'm trying to display labels on GIS polygon features in R using the st_centroid function in the sf library. Unfortunately, while the head() function seems to show that each polygon has different x and y coordinates associated with it, all labels get rendered overlapping at a single point on the map (which is apparently the centroid of one particular polygon). What am I doing wrong here?

Current code setup:

library("ggplot2")
library("sf")

sf::sf_use_s2(FALSE) #makes centroids not break

world <- st_read("C:/prgrm/gis/source/10m_land_and_islands.shp")
prov <- st_read("C:/prgrm/gis/edited ncm/ncm_provinces.shp")
prov <- cbind(prov, st_coordinates(st_centroid(prov))) #attaches centroids to 'prov' dataset

head(prov)

ggplot(data = world) + 
  geom_sf() + 
  geom_sf(data=prov, aes(fill="blue")) +
  geom_text(data=prov, aes(X,Y, label=provname_r), size=5) +
  coord_sf(xlim=c(-2000000,1000000),ylim=c(-1500000, 3000000), crs=st_crs(3310))

Solution

  • You may be better off with specifying the centroid placement via fun.geometry argument of the geom_sf_text() call / by the way the default is sf::st_point_on_surface() - which is a good default as it makes sure that the label is not placed inside a hole, should the polygon have one.

    Consider this example, using the well known & much loved nc.shp shapefile that ships with {sf}.

    library(sf)
    library(ggplot2)
    
    # in place of your world dataset
    shape <- st_read(system.file("shape/nc.shp", package="sf"))   # included with sf package
    
    # in place of your prov dataset
    ashe <- shape[1, ]
    
    ggplot(data = shape) +
      geom_sf() +
      geom_sf(data = ashe, fill = "blue") +
      geom_sf_text(data = ashe, 
                   aes(label = NAME), 
                   color = "red",
                   fun.geometry = st_centroid)
    

    enter image description here