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))
Does it look what you are looking for ?