我使用sf和ggplot2来读取shapefiles作为简单的特性和绘制各种地图。我一直在通过ggplot2书中的地图一章工作,但无法真正找到以下问题的答案:
使用geom_sf绘制地图并将其功能标记为geom_sf_text是一项非常简单的任务。
library(ggplot2)
library(sf)
library(ozmaps)
oz_states <- ozmaps::ozmap_states
ggplot() +
geom_sf(data = oz_states) +
geom_sf_text(data = oz_states, aes(label = NAME))

一旦我们放大前一张地图的一段,并不是所有的地形图中的特征标签都是可见的。
xlim <- c(120.0, 140.0)
ylim <- c(-40, -24)
ggplot() +
geom_sf(data = oz_states) +
geom_sf_text(data = oz_states, aes(label = NAME)) +
coord_sf(xlim = xlim, ylim = ylim)

我找到了一个方法,可以放大地图的各个部分,并且仍然能够通过计算特征的质心、将坐标提取为单独的列、选择我想要在最终地图中显示的元素以及使用ggrepel给它们贴上标签来标记地图中的特征。
library(dplyr)
library(ggrepel)
oz_states_labels <- oz_states %>% st_centroid()
oz_states_labels <- do.call(rbind, st_geometry(oz_states_labels)) %>%
as_tibble() %>%
rename(x = V1) %>%
rename(y = V2) %>%
cbind(oz_states_labels) %>%
slice(4,5,7,3)
ggplot() +
geom_sf(data = oz_states) +
geom_text_repel(data = oz_states_labels, aes(label = NAME, x = x, y = y)) +
coord_sf(xlim = xlim, ylim = ylim)

当然,如果可能的话,我想避免先计算质心,从结果的sf中提取坐标,然后选择要在最终地图中显示的标签。
,因此我的问题是:是否有一种更快的方法来标记在图中可见的所有元素,例如,通过在geom_sf_text或coord_sf中指定这一点
提前感谢您的提示和答案!
发布于 2021-02-03 17:20:06
我相信您所面临的问题是由于您在表示级别上应用了裁剪/您的ggplot对象的实际数据没有被裁剪。
我建议在数据层应用作物,例如通过sf::st_crop()。在本例中,我使用xlim和ylim对象的值来创建一个边界框(称为crop_factor,理由不详),在数据级别限制oz_states的范围,方法是创建一个名为oz_cropped的新对象&在原始工作流中继续。
现在,所有的质心和标签以及没有的东西都会表现得更好。
library(ggplot2)
library(sf)
library(ozmaps)
oz_states <- ozmaps::ozmap_states
crop_factor <- st_bbox(c(xmin = 120,
xmax = 140,
ymax = -24,
ymin = -40),
crs = st_crs(oz_states))
oz_cropped <- st_crop(oz_states, crop_factor)
ggplot() +
geom_sf(data =oz_cropped) +
geom_sf_text(data = oz_cropped, aes(label = NAME))

https://stackoverflow.com/questions/66031935
复制相似问题