ggplot2 和 sf:geom_sf_text 在 coord_sf 设定的范围内
ggplot2 and sf: geom_sf_text within limits set by coord_sf
我正在使用 sf
和 ggplot2
将 shapefile 读取为简单特征并绘制各种地图。我一直在研究 maps chapter in the ggplot2 book 但无法真正找到以下问题的答案:
使用 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)
我找到了一种解决方法来放大地图的各个部分,并且仍然能够通过计算特征的质心来标记图中存在的特征,将坐标提取为单独的列,select编辑我希望在最终地图中显示的元素,并使用 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
和 select 中提取坐标,最终显示的标签地图。
因此我的问题是: 是否有更快的方法来标记图中可见的所有元素,例如通过在 geom_sf_text
或 coord_sf
中指定?
提前感谢您的提示和回答!
我认为您面临的问题是由于您在 presentation 级别应用裁剪/未裁剪 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))
我正在使用 sf
和 ggplot2
将 shapefile 读取为简单特征并绘制各种地图。我一直在研究 maps chapter in the ggplot2 book 但无法真正找到以下问题的答案:
使用 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)
我找到了一种解决方法来放大地图的各个部分,并且仍然能够通过计算特征的质心来标记图中存在的特征,将坐标提取为单独的列,select编辑我希望在最终地图中显示的元素,并使用 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
和 select 中提取坐标,最终显示的标签地图。
因此我的问题是: 是否有更快的方法来标记图中可见的所有元素,例如通过在 geom_sf_text
或 coord_sf
中指定?
提前感谢您的提示和回答!
我认为您面临的问题是由于您在 presentation 级别应用裁剪/未裁剪 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))