In geom_sf_text, how to nudge x and y in aesthetics?

@dc37 provided the key to doing what I want. For the added complexity of changing coordinate systems (since ggrepel can't use the geometry list column):

Transform to different CRS:

Cities.sf.t <- st_transform( Cities.sf, crs="+proj=laea +lon_0=-107.2 +lat_0=37.6 +x_0=0 +y_0=0 +ellps=WGS84 +units=m +no_defs" )

Then copy coordinates from the geometry list column and add them to data frame as columns X and Y, which can be used for text label:

Cities.sf.t <- cbind( Cities.sf.t, st_coordinates( Cities.sf.t ) )

And finally use that one data frame for the plot:

ggplot( Cities.sf.t ) + geom_sf() + 
  geom_text_repel( aes(x=X, y=Y, label=City) )

ggrepel allows use of h/vjust as aesthetics, but they don't behave as expected, and I can't make much sense of the documentation. I'll have to use trial and error or just accept where it wants to put the labels.


As far as I can tell, vectorized input for nudge_x and nudge_y is processed correctly.

library(ggplot2)
library(sf)
#> Linking to GEOS 3.7.2, GDAL 2.4.2, PROJ 5.2.0

Cities <- read.table(text=
  "City long    lat hJust   vJust   hBump   vBump
  GrandJunction -108.550649 39.063871   1   1   -1100   -1000
  Gunnison  -106.925321 38.545825   0   1   0   -1000
  Tincup    -106.47836  38.754439   1   0   0   800",
  header=TRUE)

Cities.sf <- st_as_sf(x = Cities, 
                      coords = c("long", "lat"),
                      crs = "+proj=longlat +datum=WGS84")

ggplot(Cities.sf) + geom_sf() + 
  coord_sf(xlim = c(-109, -106.3), ylim = c(38.4, 39.2)) +
  geom_sf_text(
    aes(label = City, hjust = hJust, vjust = vJust),
    nudge_x = c(-0.025, 0.025, -0.05),
    nudge_y = c(-0.025, -0.025, 0)
  )
#> Warning in st_point_on_surface.sfc(sf::st_zm(x)): st_point_on_surface may
#> not give correct results for longitude/latitude data

Created on 2020-01-01 by the reprex package (v0.3.0)


I'm not really familiar with sf packages, but if you need to add labels on your plot and make them to not overlap your points, you can have the use of ggrepel package:

library(ggplot2)
library(sf)
library(ggrepel)
ggplot(Cities.sf) + geom_sf() + 
  coord_sf( xlim=c(-109, -106.3), ylim=c(38.4, 39.2 ) ) +
  geom_text_repel(inherit.aes = FALSE, data = Cities, aes(x = long, y = lat, label = City))

enter image description here

Does it look what you are looking for ?

Tags:

R

Ggplot2

Sf