Я хотел бы построить карту с помощью geom_sf() и добавить метки, как показано на следующей карте, созданной вручную (но нам не нужны цвета или легенда, это просто карта, которая у нас была под рукой).
Новая карта:
Данные карты можно скачать здесь. Карта состоит из трех столбцов: «Kommunenummer» (номер муниципалитета), «Kommunenavn» (название муниципалитета), «геометрия». На карте выше указаны два объекта: муниципалитеты Волда (юг) и Тромсё (север).
Я думаю, нам нужно будет определить положение центроида этих муниципалитетов, а затем использовать что-то вроде geom_text_repel(), чтобы указать на них, но у меня это не получилось. Есть ли у кого-нибудь советы?
Минимальный рабочий пример:
mapdata <- st_read("~/Downloads/Basisdata_0000_Norge_25833_NorskeFylkerKommunerIllustrasjonsdata2021_GeoJSON/kommuner2021.json")
ggplot(mapdata) +
geom_sf() +
theme_minimal() +
theme(
panel.grid.major = element_blank(), # Removes major grid lines
panel.grid.minor = element_blank(), # Removes minor grid lines
axis.text.x = element_blank(), # Removes x-axis labels (Longitude)
axis.text.y = element_blank(), # Removes y-axis labels (Latitude)
axis.title.x = element_blank(), # Removes x-axis title
axis.title.y = element_blank() # Removes y-axis title
)
Если вы не работаете с сотнями лейблов, ggrepel
зачастую не самый эффективный подход. Вы можете потратить слишком много времени на то, чтобы метки отображались правильно, а исправление проблем может создать проблемы в другом месте.
Обычно мне проще использовать пакет sf
и создавать геометрию этикеток вручную. Чтобы правильно расположить метки, может потребоваться некоторое время методом проб и ошибок, но, имея всего несколько меток, почти всегда легче получить желаемый результат, чем при использовании ggrepel
. Кроме того, я не уверен, что ggrepel
принимает функции, например. ggtext
, чтобы можно было использовать шрифты разного размера для меток графиков.
В этом ревыражении используется одинаковое смещение -/+0,5 десятичных градусов для обеих меток. Ничто не мешает вам установить разные смещения для каждой метки. Поскольку мой норвежский язык немного «заржавел», я не смог загрузить связанные с вами данные, поэтому применил этот рабочий процесс к встроенному набору данных ЧПУ. Ваши смещения могут отличаться от CRS ваших фактических данных.
Я использовал st_point_on_surface()
вместо st_centroid()
, чтобы точка не отображалась за пределами многоугольника (что может произойти с некоторыми многоугольниками неправильной формы). Обратите внимание: st_point_on_surface()
вряд ли отобразит истинное местоположение центроида в тех случаях, когда в противном случае st_centroid()
нарисовал бы его внутри многоугольника. Если это нежелательно, замените st_point_on_surface()
на st_centroid()
.
Загрузите пакеты и пример данных карты:
library(sf)
library(dplyr)
library(ggplot2)
# Example data
mapdata <- st_read(system.file("shape/nc.shp", package = "sf"))
Создайте геометрию этикетки:
# Create 'centroids' of municipalities (you can safely ignore the warning)
sf_centroids <- mapdata %>%
filter(NAME %in% c("Watauga", "Swain")) %>% # proxies for your municipalities
st_point_on_surface()
# Create points for label locations
sf_labels <- sf_centroids %>%
mutate(lon = st_coordinates(.)[,1] - 0.5,
lat = st_coordinates(.)[,2] + 0.5) %>%
st_drop_geometry() %>%
st_as_sf(coords = c("lon", "lat")) %>%
st_set_crs(st_crs(sf_centroids))
# Create lines between label locations and centroids
sf_lines <- rbind(sf_labels[,"NAME"],
sf_centroids[,"NAME"]) %>%
group_by(NAME) %>%
summarise(geometry = st_union(geometry)) %>%
st_cast("LINESTRING")
Создайте списки меток и постройте график:
# Create labels
labels1 <- c("Exp's 2-3 - Northern Norway:", "Exp 1 - Sunnmøre:")
labels2 <- c("Bokmål vs. Northern Norwegian Dialect", "Bokmål")
# Plot labels using geo_sf_text
ggplot() +
geom_sf(data = mapdata) +
geom_sf(data = sf_lines, linewidth = 0.15) +
geom_sf(data = sf_labels, shape = 21, fill = "white", size = 0.75) +
geom_sf(data = sf_centroids, size = 0.75) +
geom_sf_text(data = sf_labels,
aes(label = labels1),
size = 2,
vjust = -2,
fun.geometry = st_centroid,
colour = "black") +
geom_sf_text(data = sf_labels,
aes(label = labels2),
size = 1.5,
vjust = -1,
fun.geometry = st_centroid,
colour = "black") +
coord_sf(clip = "off") +
theme_void()
Отлично! Спасибо! Гораздо более элегантное решение, чем то, что мне удалось с помощью ggrepel.