ggplot2 - 선그래프 위에 일부 위치에만 point 설정하기

선그래프 위에서 일정 위치를 강조하고 싶을때, 점으로 표시하는게 일반적인 방법이다. 모든 좌표에 점으로 표시하는건 그리 어렵진 않지만, 일부 강조하고싶은 좌표위에만 포인트를 주는건 쉽지 않다. 방법은 2가지정도 있는데, 첫번째 방법은 기존 데이터셋에 포인트를 주기위한 별도의 x,y 필드를 추가하면서 포인트를 주기위한 위치가 아니면 무조건 NA로 셋팅하는 방법이다. 이방법은 굳이 하나의 데이터 셋으로 관리해야만 하는 상황이 아닌이상 별로 권하진 않는다.

두번째 방법은 포인트를 그리기위한 데이터셋을 별도로 만드는 방법이다. 이 포스팅은 두번째 방법을 사용할 것이며, 아래와 같이 많은 좌표가 있지만 3개의 포인트만 추가해서 그려볼 예정이다.

데이터 준비하기

이번에 사용할 데이터는 채권금리인데, 관련 데이터 가져오는 방법은 여기를 클릭해서 참고한다.

tb1 = read_excel(path = "./2022/20221119/data2.xls",
                 skip = 3, 
                 col_names = c("일자","국고채", "회사채"))

tb2 = tb1 %>% 
  mutate(bond1 = as.numeric(국고채),
         bond2 = as.numeric(회사채)) %>% 
  mutate(gap = bond2 - bond1) %>% 
  mutate(date = ymd(일자)) %>% 
  select(date, gap)
# A tibble: 217 × 2
   date         gap
   <date>     <dbl>
 1 2022-11-18  1.64
 2 2022-11-17  1.62
 3 2022-11-16  1.61
 4 2022-11-15  1.59
 5 2022-11-14  1.57
 6 2022-11-11  1.53
 7 2022-11-10  1.52
 8 2022-11-09  1.51
 9 2022-11-08  1.49
10 2022-11-07  1.48
# … with 207 more rows

이 선그래프 위에 3개의 점을 그릴 예정인데, 그 좌표의 정보를 담은 데이터셋을 별도로 만든다. 선그래프용으로 데이터셋이 하나, 포인트를 그릴 데이터셋이 하나, 총 2개가 필요한 셈이다.

sb1 = tibble(date = c("20220103", "20220928", "20221118")) %>% 
  mutate(date = as.Date(date, "%Y%m%d"))

tb3 = tb2 %>% 
  inner_join(sb1)

# A tibble: 3 × 2
  date         gap
  <date>     <dbl>
1 2022-11-18 1.64 
2 2022-09-28 1.00 
3 2022-01-03 0.605

그래프 그리기

선그래프를 먼저 그려준다.

ggplot(tb2, aes(date, gap)) +
  geom_line()

그 선그래프 위에 3개의 포인트를 그린다. 보면 geom_linegeom_point에 사용된 데이터셋이 각기 다르다는 것을 알 수 있다. 이런식으로 다른 데이터의 기준으로 각기 그래프를 그려서 결국 한판의 그래프로 통합할 수 있게 된다.

ggplot() +
  geom_line(data = tb2, aes(date, gap), size = 1) +
  geom_point(data = tb3, aes(date, gap), size = 3, colour = "gray0")

데이터위에 강조하고 싶은 수치(text)를 추가한다. 약간의 포인트 설정과 테마도 변경해봤다. 그런데 보면 텍스트가 일부 잘려 보이지 않거나, 너무 한쪽에 붙어 보여 약간의 이동이 필요하다고 느껴진다.

ggplot() +
  geom_line(data = tb2, aes(date, gap), size = 1) +
  geom_point(data = tb3, aes(date, gap), size = 3, colour = "gray0") +
  geom_point(data = tb3, aes(date, gap), size = 1, colour = "gray100") +
  geom_text(data = tb3, aes(date, gap, label = gap), 
            vjust = c(-2, 2.5, -2), family = "BMJUAOTF") +
  theme_bw()

이럴 때 사용하는게 expand 설정값이다. 디폴트값은 0.05로 되어 있으며 5%씩 할당되있다보면 된다. 조금씩 여유롭게 셋팅하니 안보이던 텍스트값이 보인다.

ggplot() +
  geom_line(data = tb2, aes(date, gap), size = 1) +
  geom_point(data = tb3, aes(date, gap), size = 3, colour = "gray0") +
  geom_point(data = tb3, aes(date, gap), size = 1, colour = "gray100") +
  geom_text(data = tb3, aes(date, gap, label = gap), 
            vjust = c(-2, 2.5, -2), family = "BMJUAOTF") +
  scale_y_continuous(expand = expansion(c(0.2, 0.3))) +
  scale_x_date(expand = expansion(c(0.1, 0.1))) +
  theme_bw()

마지막으로 x축의 레이블을 포인트 위치만 표시되도록 조정하면 끝이다.

ggplot() +
  geom_line(data = tb2, aes(date, gap), size = 1) +
  geom_point(data = tb3, aes(date, gap), size = 4, colour = "gray0") +
  geom_point(data = tb3, aes(date, gap), size = 2, colour = "gray100") +
  geom_text(data = tb3, aes(date, gap, label = gap), 
            vjust = c(-2, 2.5, -2), family = "BMJUAOTF") +
  scale_y_continuous(expand = expansion(c(0.2, 0.3))) +
  scale_x_date(expand = expansion(c(0.1, 0.1)),
               breaks = pull(tb3, "date"),
               date_labels = "%m/%d") +
  theme_bw()


더 보면 좋을 글들