R프로그래밍으로 간단한 간트차트(Gantt Chart) 만들기

ggplot2 패키지의 geom_crossbar 함수는 중앙값 또는 평균과 같은 중심 경향을 보여주는 막대를 포함하여 범위를 시각화하는 데 유용하다. 하지만, 용도와 다르게 아래와 같이 간트차트(Gantt Chart)를 만드는 도구로 사용해 볼 예정이다. 간트차트는 주로 프로젝트 관리에서 작업 일정과 진행 상황을 시각적으로 표현하는 도구로, 작업의 시작 및 종료 시점과 기간을 막대 형태로 보여준다.

geom_crossbar 기본기능

간트차트를 만들기 앞서 geom_crossbar 를 이용하여 그래프가 어떻게 그려지는지 알아보자. 데이터는 5개의 막대를 그리기위해 임의의 값으로 셋팅했다.

tb1 = tibble(x = c(0, 4, 5, 10, 11), 
             y = c("A", "B", "C", "D", "E"), 
             se = c(2,3,4,4,3))
tb1$y = factor(tb1$y, levels = rev(unique(tb1$y)))

geom_crossbar 는 단순히 x,y 값만 필요한게 아니라, min과 max 값을 지정해야 한다. x,y축 둘다 지정할 필요는 없고, 하나의 축을 기준으로 하면 된다. 그려보면, 가운데 기준선이 있고, 그 양옆에 범위에 해당하는 min/max 값에 해당하는 막대그래프 영역이 그려진다.

ggplot(tb1) +
  geom_crossbar(aes(x = x, y = y, 
                    xmin = x - se, 
                    xmax = x + se))

극단적인 예를 들어서, x 값을 -5 처리해서 만약 그려보면, 중심선만 밖으로 나와 그려지는 걸 볼 수 있다.

ggplot(tb1) +
  geom_crossbar(aes(x = x - 5, y = y, 
                    xmin = x - se, 
                    xmax = x + se))

내가 그리려는 간트차트는 이런 중심선이 필요없다. 그 중심선의 굵기를 0 으로 만드는 옵션이 fatten 이다.

ggplot(tb1) +
  geom_crossbar(aes(x = x, y = y, 
                    xmin = x - se, 
                    xmax = x + se), fatten = 0)

간트차트 만들기

간트차트를 만들기 위해, 프로젝트 일정같은 임의의 데이터를 만들었다. factor 로 변경한 이유는 y축 기준의 막대정렬을 내가 원하는 대로 변경하기 위함이다. (Planning –> Develop 순서)

v_grp = c("Planning", "Research", "Design", "Review", "Develop")
tb2 = tibble(grp = v_grp, 
                 xmin = c(0,4,4, 10, 14), 
                 xmax = c(7,10,20,20,20)) |> 
  mutate(grp = factor(grp, levels = rev(v_grp)))

데이터는 준비되었으니, geom_crossbar 로 그리면 된다. 간트차트 특성상 중심선의 의미가 없어 fatten = 0 으로 삭제했다.

ggplot() +
  geom_crossbar(aes(y = grp, x = xmin, xmin = xmin, xmax = xmax), 
                data = tb2, fill = "#A5D7FB", fatten = 0, width = 0.3, colour = NA)

그래프가 좀 밋밋하길래, 일부 일정 부분을 강조하기 위해 추가 데이터를 선언하고, 그 위에 막대를 다른색으로 덧대어 그렸다.

tb3 = tibble(grp = c("Design", "Review"), 
             xmin = c(4, 10), 
             xmax = c(13,15)) |> 
  mutate(grp = factor(grp, levels = rev(v_grp)))

ggplot() +
  geom_crossbar(aes(y = grp, x = xmin, xmin = xmin, xmax = xmax), 
                data = tb2, fill = "#A5D7FB", fatten = 0, width = 0.3, colour = NA) +
  geom_crossbar(aes(y = grp, x = xmin, xmin = xmin, xmax = xmax), 
                data = tb3, fill = "#4295E4", fatten = 0, width = 0.3, colour = NA)

불필요한 선들을 정리하고, 색상을 입혀 디자인을 마무리하면 아래와 같이 그릴 수 있다. 복잡한 일정을 가지고 한번 만들어봐도 좋을 거 같고, 우선은 일부 단순하고 간단한 컨셉용으로 만들기에는 부족함이 없을 듯 하다.


더 보면 좋을 글들