在geom_sf_text中,如何在美学上微调x和y?

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

我想使用 sf 微调 ggplot2 中文本的 x 和 y 位置。文本的对齐可以在美学中修改,这就需要微调也进行类似的修改,但是 nudge_x 和 nudge_y 不能在美学中使用。

使用 sp 和强化数据框,我可以在美学上修改 x 和 y ( x=(x+hBump), y=(y+vBump) 。我不知道这在 sf 中是否可行。

以下是一些数据:

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 )

转换为 sf

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

ggplot(coord_sf 只是为了防止标签脱落)

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))

现在如果我们推动一个,其他的可能会搞砸。 需要审美推动!

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 = 0.025, nudge_y = -0.025
  )

附带问题 - 我想如果我将对象转换为另一个 crs 使用米,那么微调单位必须从度变为米?这就是 hBump 和 vBump 所在的单位。

我不太熟悉 sf 包,但是如果你需要在你的图上添加标签并使它们不与你的点重叠,你可以使用 ggrepel 包:

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))

它看起来像您要找的东西吗?

@dc37 提供了做我想做的事情的关键。对于更改坐标系的额外复杂性(因为 ggrepel 不能使用几何列表列):

转换为不同的 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" )

然后从几何列表列复制坐标并将它们添加到数据框中 X 和 Y 列,可用于文本标签:

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

最后将那个数据框用于绘图:

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

ggrepel 允许使用 h/vjust 作为美学,但它们的行为并不像预期的那样,我无法理解文档。我将不得不使用反复试验或只接受它想要放置标签的位置。

据我所知,nudge_xnudge_y 的向量化输入得到了正确处理。

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

reprex package (v0.3.0)

于 2020-01-01 创建