지역명 겹치지 않게 배치하기
개요
지난번 지역명 표기하기 글에서 수도권 지도를 그리고 시군구명을 표기했습니다. 폴리곤 크기가 작은 지역들이 인접해 있는 경우, 아래 그림처럼 지역명이 서로 겹치는 문제가 발생합니다. 이번 글에서는 이러한 텍스트 중첩 문제를 해결하기 위한 두 가지 주요 방법을 소개합니다. 하나는 geom_text_repel 함수를 사용해 텍스트를 자동으로 분산 배치하는 방법이고, 다른 하나는 특정 기준에 따라 일부 지역명을 생략하여 지도를 간소화하는 방법입니다.
# 패키지 로드
library(tidyverse)
library(sf)
library(ggplot2)
library(showtext)
# 데이터 불러오기
sdg <- st_read("아웃풋/수도권 행정구 병합 지도.shp") %>%
separate(col = SGG_NM,
into = c("SD_NM", "SGG_NM"),
sep = " ",
fill = "right")
## Reading layer `수도권 행정구 병합 지도' from data source
## `...\아웃풋\수도권 행정구 병합 지도.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 66 features and 2 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -10044.95 ymin: 477264 xmax: 274945.2 ymax: 631207.8
## Projected CRS: Korea_2000_Korea_Central_Belt_2010
# 글꼴 설정
font_add("kopub", "C:/Users/.../AppData/Local/Microsoft/Windows/Fonts/KoPub Dotum Medium.ttf")
showtext_auto()
showtext_opts(dpi=300)
theme.size = 12
text.size = theme.size / .pt
# 지도 작성
ggplot(data = sdg) +
geom_sf(colour = "gray40", fill = "#eaeaea", linewidth = 0.5) +
geom_sf_text(aes(label = SGG_NM),
family = "kopub",
size = text.size) +
theme_void()

geom_text_repel 함수로 지역명 분산 배치하기
첫 번째 방법은 ggrepel 패키지의 geom_text_repel 함수를 사용하는 것입니다. 이 함수는 텍스트가 서로 겹치지 않도록 간격을 자동으로 조정하여 분산 배치합니다. sf 객체에 사용하려면 stat = "sf_coordinates"를 지정해야 합니다.
이 함수의 주요 인자로는 force와 force_pull이 있습니다. force로 텍스트 라벨들끼리 얼마나 강하게 밀어낼지를 설정합니다. 값이 클수록 라벨이 더 멀리 분산됩니다. force_pull로 텍스트 라벨이 데이터 포인트에 얼마나 강하게 끌리는지를 설정합니다. 값이 작을수록 라벨이 데이터 포인트에서 더 멀이 떨어질 수 있습니다.
아래는 주요 인자를 기본값으로 두고 geom_text_repel 함수를 사용해 지역명이 겹치는 문제를 해결하려고 한 코드입니다. 하지만, 지도가 복잡하기 때문에 geom_text_repel 함수로는 모든 지역명을 적절히 배치하기 어려워 보입니다. force와 force_pull 값을 조정하더라도 이 문제를 완벽히 해결하기 쉽지 않아 보입니다.
# 패키지 로드
library(ggrepel)
# 지도 작성
ggplot(data = sdg) +
geom_sf(colour = "gray40", fill = "#eaeaea", linewidth = 0.5) +
geom_text_repel(aes(label = SGG_NM, geometry = geometry),
stat = "sf_coordinates",
family = "kopub",
size = text.size) +
theme_void()

일부 지역명 생략하기
두 번째 방법은 일부 지역명을 생략하는 것입니다. 예를 들어, 폴리곤 면적이 중위값보다 작은 지역명을 생략하여 주요 지역명만 지도에 남깁니다.
# 폴리곤 면적 계산
sdg <- sdg %>%
mutate(면적 = as.numeric(st_area(sdg)))
# 지도 작성
ggplot(data = sdg) +
geom_sf(colour = "gray40", fill = "#eaeaea", linewidth = 0.5) +
geom_sf_text(aes(label = ifelse(sdg$면적 < median(sdg$면적), "", SGG_NM)),
family = "kopub",
size = text.size) +
theme_void()

이번 글에서는 지도에서 텍스트가 겹칠 때 이를 해결하는 두 가지 방법을 소개했습니다. geom_text_repel 함수는 텍스트를 자동으로 분산 배치해 주지만, 복잡한 지도에서는 모든 텍스트를 완벽히 배치하기 어렵습니다. 반면, 특정 기준에 따라 일부 지역명을 생략하는 방법은 중요한 정보만 표시하여 깔끔한 지도를 만들 수 있지만, 일부 정보가 누락될 수 있다는 점을 고려해야 합니다. 각각의 장단점을 잘 살펴보고, 시각화의 목적에 맞는 방법을 선택해 활용해 보세요!