일부 텍스트만 표기하기

개요

선 그래프를 그릴 때 모든 텍스트를 표기하면 그래프가 복잡해지고 가독성이 떨어질 수 있습니다. 이를 해결하기 위해, 중요한 데이터 포인트에만 텍스트를 추가하여 시각화의 명확성을 높이는 방법을 소개합니다. 이번 글에서는 1995년부터 2023년까지 서울특별시, 인천광역시, 경기도의 주민등록인구 데이터를 선 그래프로 시각화하고, 각 시도의 최대값과 최소값에만 텍스트를 표기해 강조하는 방법을 다뤄보겠습니다.

데이터 준비하기

먼저, 필요한 패키지를 로드하고 차트에서 사용할 글꼴을 설정합니다. ggplot2 패키지를 활용해 선 그래프와 텍스트 표기를 구현할 예정입니다.

# 패키지 로드
library(readxl)
library(tidyverse)
library(ggplot2)
library(showtext)
library(scales)

# 차트 글꼴 설정
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

통계청에서 제공하는 1995~2023년 시도별 주민등록인구 데이터에서 서울특별시, 인천광역시, 경기도 데이터를 추출하여 분석에 적합한 형태로 가공합니다.

# 데이터 로드
data <- read_xlsx("데이터/주민등록인구_시도_1995-2023.xlsx")

# 데이터 가공
data <- data %>% 
  rename(시도 = 행정구역별,
         주민등록인구수 = `계 (명)`) %>% 
  filter(시도 %in% c("서울특별시", "인천광역시", "경기도")) %>% 
  mutate(시점 = as.character(시점),
         주민등록인구수 = as.numeric(주민등록인구수) / 10000)

# 데이터 확인
head(data)
## # A tibble: 6 × 3
##   시도       시점  주민등록인구수
##   <chr>      <chr>          <dbl>
## 1 서울특별시 1995           1055.
## 2 서울특별시 1996           1042.
## 3 서울특별시 1997           1034.
## 4 서울특별시 1998           1027.
## 5 서울특별시 1999           1026.
## 6 서울특별시 2000           1031.

선그래프 그리기

1995년부터 2023년까지의 주민등록인구 변화를 시각화하기 위해 선 그래프를 그립니다. X축에는 시점, Y축에는 주민등록인구수를 매핑하고, 시도를 기준으로 그룹화해 선을 그립니다. 색상은 시도별로 다르게 지정하고, 각 데이터 포인트를 강조하기 위해 점도 추가합니다.

data %>% 
  ggplot(aes(x = 시점, y = 주민등록인구수, 
             group = 시도, color = 시도)) +
  geom_line(linewidth = 0.4) +
  geom_point(size = 3) +
  scale_x_discrete(name = "") +
  scale_y_continuous(name = "주민등록인구 수(만 명)",
                     expand = expansion(mult = c(0, 0.1))) +
  theme_minimal(base_size = theme.size, base_family = "kopub") +
  theme(
    axis.line = element_line(linewidth = 0.5, color = "gray10"),
    axis.ticks = element_line(linewidth = 0.1, color = "gray10"),
    
    panel.grid.minor = element_blank(),
    
    axis.text = element_text(color = "gray10")
    )

1995~2023년 서울, 인천, 경기 주민등록인구 추이 그래프

최대값과 최소값 텍스트 표기하기

최대값과 최소값에만 텍스트를 추가하기 위해, 해당 값을 식별하는 라벨 칼럼을 생성합니다. 이 칼럼은 최대값 또는 최소값에 해당하는 경우 값을 반환하고, 나머지 값은 NA를 반환하도록 설정합니다. 그래프에서 이 라벨 칼럼을 이용해 텍스트를 추가합니다.

이번 예제에서는 공교롭게도 최소값과 최대값이 각각 그래프의 양 끝 지점에 해당해서 텍스트가 축에 가려 잘리는 문제가 발생합니다. scale_x_discrete 함수의 expand 매개변수를 사용해 X축에 여백을 추가해 문제를 해결해 줍니다. 이를 통해 그래프의 좌우에 공간을 확보하여 텍스트가 잘리지 않도록 조정할 수 있습니다.

data2 <- data %>% 
  group_by(시도) %>% 
  mutate(라벨 = case_when(주민등록인구수 == min(주민등록인구수) ~ 주민등록인구수,
                        주민등록인구수 == max(주민등록인구수) ~ 주민등록인구수,
                        T ~ as.numeric(NA)),
         시도 = factor(시도, levels = c("서울특별시", "인천광역시", "경기도")))

data2 %>% 
  ggplot(aes(x = 시점, y = 주민등록인구수, 
             group = 시도, color = 시도)) +
  geom_line(linewidth = 0.4) +
  geom_point(size = 3) +
  geom_text(aes(label = comma(라벨, accuracy = 1)),
            vjust = -1,
            family = "kopub",
            size = text.size,
            color = "gray10") +
  scale_x_discrete(name = "",
                   expand = expansion(mult = 0.05)) +
  scale_y_continuous(name = "주민등록인구 수(만 명)",
                     expand = expansion(mult = 0.2),
                     labels = comma_format()) +
  scale_color_brewer(palette = "Dark2") +
  theme_minimal(base_size = theme.size, base_family = "kopub") +
  theme(
    axis.line = element_line(linewidth = 0.5, color = "gray10"),
    axis.ticks = element_line(linewidth = 0.1, color = "gray10"),
    
    panel.grid.minor = element_blank(),
    
    axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1),
    
    legend.position = "bottom",
    legend.title = element_blank()
    )

1995~2023년 서울, 인천, 경기 주민등록인구 추이에 최소값, 최대값 텍스트 표기한 그래프

이 방법을 활용하면 모든 텍스트를 표기하지 않아도 중요한 데이터 포인트를 효과적으로 강조할 수 있습니다. 특히 데이터가 많거나 복잡할 때 가독성을 높이고 핵심 정보를 전달하기에 적합합니다. 필요에 따라 특정 조건에 따라 텍스트를 추가하거나 제거하는 방식으로 응용해 보세요!