원형 막대 그래프
원형 막대 그래프는 막대 그래프를 둥글게 표현한 그래프이다. 사실 둥글게 데이터를 표현하는 시각화 방식은 데이터가 원의 중심으로 고르게 표현되다 보니 한 눈에 데이터를 살펴보기가 좋지만 최근 선호되지는 않는 방식이다. 특히 파이 차트의 경우 그 내부의 구성 비율을 나타내기 위해 많이 사용되지만 사람의 눈으로 그 비율을 정확하게 비교하기란 쉬운 일이 아니어서 데이터를 정확히 파악할 수 없다는 단점이 이다. 그래서 파이 차트는 내부에 표시되는 데이터를 가급적 줄여서 중요한 몇 개의 데이터의 비율을 표현하는데 사용된다. 반면 막대 그래프의 경우 가로로 배열된 수평형 막대 그래프는 대부분 공간의 제약으로 많은 막대를 표현하지 못한다. 그래서 세로로 배열된 수직형 막대 그래프를 사용하는데 이 경우도 데이터가 많아질 경우 한눈에 비교하기가 어렵다. 그래서 원형 그래프와 막대 그래프의 장점을 사용한 것이 원형 막대 그래프이다.
원형 막대 그래프는 수평형 막대 그래프보다 더 많은 데이터의 표현이 가능하고 원의 중심으로 균등하게 데이터가 배치되기 때문에 전체 데이터를 한눈에 파악하기 쉽다는 장점이 있다. 하지만 막대의 길이를 정확하게 비교하기가 어렵기 때문에 멀리 떨어진 데이터의 비교가 어렵다는 단점이 있다. 따라서 원형 막대 그래프는 여러 그룹으로 구분된 막대 그래프를 원형으로 그려줌으로써 그룹간의 비교, 그룹내의 비교를 한눈에 파악하기 쉽게 그려주는게 바람직하다.
본 포스트에서는 원형 막대 그래프를 위해 주로 ggplot2
를 사용하겠지만 원형 텍스트를 그리기 위해 geomtextpath
패키지를 사용하였다. 사용하는 데이터는 교육통계 서비스 홈페이지에서 제공하는 2020년 취업통계 데이터 셋 을 사용하겠다. 2020년 취업통계 데이터 셋을 불러 들이는 코드는 다음과 같다.
library(readxl)
library(tidyverse)
library(patchwork)
library(showtext)
showtext_auto()
df_취업통계 <- read_excel('2020년 학과별 고등교육기관 취업통계.xlsx',
## '학과별' 시트의 데이터를 불러오는데,
sheet = '학과별',
## 앞의 13행을 제외하고
skip = 13,
## 첫번째 행은 열 이름으로 설정
col_names = TRUE,
## 열의 타입을 설정, 처음 9개는 문자형으로 다음 79개는 수치형으로 설정
col_types = c(rep('text', 9), rep('numeric', 79)))
## df_취업통계에서 첫번째부터 9번째까지의 열과 '계'로 끝나는 열을 선택하여 다시 df_취업통계에 저장
df_취업통계 <- df_취업통계 |> select(1:9, ends_with('계'), '입대자')
일단 표현해야 할 데이터들 전처리하겠다. 여기서 필요한 데이터는 전체 학과를 ‘전문대학과정’, ‘대학과정’, ’대학원과정’의 과정별로 구분하고 각각의 과정에 속한 학과들을 7대 계열(인문, 사회, 자연, 공학, 교육, 의약, 예체능)로 그룹화하여 취업률의 평균값이다. 여기에 각각의 과정별 취업률 평균을 산출한다.
## 데이터 표현 순서를 설정하기 위해 과정구분 팩터의 순서 설정
df_취업통계$과정구분 = fct_relevel(df_취업통계$과정구분, '전문대학과정', '대학과정', '대학원과정')
## 데이터 표현 순서를 설정하기 위해 대계열 팩터의 순서 설정
df_취업통계$대계열 = fct_relevel(df_취업통계$대계열, '인문계열', '사회계열', '교육계열', '자연계열', '공학계열', '의약계열', '예체능계열')
## 과정구분별 대계열별 데어터와 취업률 산출
df_취업통계_계열별 <- df_취업통계 |>
group_by(과정구분, 대계열) |>
summarise(졸업자 = sum(졸업자_계),
취업자 = sum(취업자_합계_계),
진학자 = sum(진학자_계),
입대자 = sum(입대자),
취업불가능자 = sum(취업불가능자_계),
외국인유학생 = sum(외국인유학생_계),
제외인정자 = sum(제외인정자_계),
## 백분률인 취업률은 그 자체로 합계나 평균을 낼 수 없으니 각 그룹별로 재계산
취업률 = 취업자 / (졸업자 - (진학자+입대자+취업불가능자+외국인유학생+제외인정자))) |>
## 계열의 표시 순서를 설정하기 위해 레벨을 재조정
arrange(과정구분, 대계열) |>
ungroup() |>
## 막대 순서 설정을 위한 일련번호 생성
mutate(id = seq(1:n())) |>
## 대계열 이름과 데이터 값을 표현하기 위한 텍스트 각도 계산
mutate(angle = 90 - (id-0.5)/n() * 360) |>
## 180도 넘어가는 막대의 각도를 180도 돌려 거꾸로 문자열이 표시되는 것을 방지
mutate(angle1 = case_when(
id > n()/2 ~ angle + 180,
id <= n()/2 ~ angle
))
## 과정별 취업률 평균 산출
df_취업통계_과정별 <- df_취업통계 |>
group_by(과정구분) |>
summarise(졸업자 = sum(졸업자_계),
취업자 = sum(취업자_합계_계),
진학자 = sum(진학자_계),
입대자 = sum(입대자),
취업불가능자 = sum(취업불가능자_계),
외국인유학생 = sum(외국인유학생_계),
제외인정자 = sum(제외인정자_계),
## 백분률인 취업률은 그 자체로 합계나 평균을 낼 수 없으니 각 그룹별로 재계산
취업률 = 취업자 / (졸업자 - (진학자+입대자+취업불가능자+외국인유학생+제외인정자))) |>
## 계열의 표시 순서를 설정하기 위해 레벨을 재조정
arrange(과정구분) |>
ungroup() |>
mutate(id = seq(1:n())) |>
mutate(angle = 90 - (id-0.5)/n() * 360) |>
mutate(angle1 = case_when(
id >= n()/2 ~ angle + 270,
id < n()/2 ~ angle -90,
))
df_취업통계_전체 <- df_취업통계 |>
summarise(## 백분률인 취업률은 그 자체로 합계나 평균을 낼 수 없으니 각 그룹별로 재계산
취업률 = sum(취업자_합계_계) / (sum(졸업자_계) - (sum(진학자_계)+sum(입대자)+sum(취업불가능자_계)+sum(외국인유학생_계)+sum(제외인정자_계)))) |>
select(취업률) |>
pull()
데이터가 준비됐다면 기본 그래프를 그려보겠다. 기본 그래프는 막대 그래프로 계열별 취업률 막대그래프인데 과정별, 대계열별 순서로 설정해 준 일련번호의 순서대로 막대 그래프를 그려준다.
## 그래프에 사용할 폰트를 설정
font_add('NanumBarunGothic', 'c:/windows/fonts/NanumBarunGothic.ttf')
p_circular <- df_취업통계_계열별 |>
ggplot(aes(x = id, y = 취업률, fill = 대계열)) +
geom_col(position = 'dodge', show.legend = F)+
scale_y_continuous(labels = scales::percent, limits = c(-0.5, 1.2)) +
scale_x_continuous(limits = c(0.5, 21.5)) +
scale_fill_brewer(palette = 'Set3') +
theme(plot.title = element_text(hjust = 0.5, size = 20),
plot.margin = margin(0.25, 0, 0, 0),
text = element_text(family = 'NanumBarunGothic'))
p_circular
이제 각각의 과정을 알아보기 쉽게 사각형을 그려 그룹을 표현해준다.
p_circular <- p_circular +
annotate(xmin = 0.5, xmax = 7.5, ymin = -0.1, ymax = 1, alpha = 0.1, geom = 'rect', fill = 'red') +
annotate(xmin = 7.5, xmax = 14.5, ymin = -0.1, ymax = 1, alpha = 0.1, geom = 'rect', fill = 'green') +
annotate(xmin = 14.5, xmax = 21.5, ymin = -0.1, ymax = 1, alpha = 0.1, geom = 'rect', fill = 'blue')
p_circular
이제 각 그룹별 평균을 표현해준다. 각각의 그룹은 7개의 막대로 그룹화되어 있기 때문에 geom_segment()
의 x
와 xend
를 7개의 막대길이로 설정하고 y
는 각각의 그룹별 평균으로 매핑하여 선을 그려준다.
p_circular <- p_circular +
geom_segment(data = df_취업통계_과정별, aes(x = 0.5+((id-1)*7), xend = 7.5+((id-1)*7), y = 취업률, yend = 취업률, color = as.factor(id)), inherit.aes = F, show.legend = F)
p_circular
이제 이 막대 그래프의 좌표계를 극좌표계로 바꾸어 그래프를 둥글게 말아준다. ggplot2
에서 제공하는 coord_polar()
를 사용해도 되지만 geomtextpath
패키지의 coord_curvedpolar()
를 사용한다. coord_curvedpolar()
는 마지막에 둥근 텍스트를 위해 설정하는 극좌표계이다.
library(geomtextpath)
p_circular <- p_circular +
coord_curvedpolar() +
theme_void()
p_circular
이제 각 막대에 해당하는 계열 이름과 취업률 값을 표기해준다. 우선 사용할 폰트를 설정해주고 geom_text()
를 사용하여 텍스트를 표기하는데 각도를 앞의 전처리 과정에서 산출한 각각의 텍스트 각도를 매핑해 줌으로써 각각의 라벨의 각도를 돌려가며 표기해 준다.
## df_취업통계_계열별 데이터프레임에서 x축은 id, y축은 0.5, 라벨은 대계열이름과 취업률을 붙이고 anble은 앞에서 설정한 angle1을 사용하여 텍스트를 표기해주고 다른 미적요소를 설정
p_circular <- p_circular +
geom_text(data = df_취업통계_계열별, aes(x=id, y=0.5, label=paste0(대계열, ', ', round(취업률*100, 1), '%'), angle= angle1), color="black", inherit.aes = FALSE, hjust = 0.5, size = 5)
p_circular
이제 각각의 과정에 대한 라벨을 붙여준다. geom_text()
를 사용하면 가로로 길게 문자열이 표시된다.
p_circular +
geom_text(data = df_취업통계_과정별,aes(x = 4+((id-1)*7), y = 1.0, label = paste0(과정구분, ', ', round(취업률*100, 1), '%'), color = as.factor(id)), inherit.aes = F, show.legend = F, size = 5)
이것도 괜찮지만 좀더 보기 좋게 만들기 위해 원형으로 둥근 문자열을 표기해주는 geom_textpath()
를 사용한다.
p_circular <- p_circular +
geom_textpath(data = df_취업통계_과정별,aes(x = 4+((id-1)*7), y = 1.0, label = paste0(과정구분, ', ', round(취업률*100, 1), '%'), color = as.factor(id)), inherit.aes = F, show.legend = F, rich = TRUE, family = 'NanumBarunGothic', size = 8)
p_circular
중앙에 빈 곳에 추가적인 정보를 제공해주면 좋을 듯 하다. 여기에는 전체 취업률을 표기해주겠다.
p_circular <- p_circular +
annotate(x = 0.5, y = -0.35, geom = 'text', label = '전체취업률', size = rel(8)) +
geom_text(aes(x = 0.5, y = -0.5, label = paste0(round(df_취업통계_전체, 3)*100, '%')), size = rel(10))
p_circular
'ggplot2' 카테고리의 다른 글
벤다이어그램 in R (6) | 2022.02.19 |
---|---|
회귀방정식이 표기된 ggplot2 in R (0) | 2022.02.19 |
대학 입학생별 학과수 - 축 변환 in R (0) | 2021.12.04 |
대학 입학생별 학과수 - ggplot2로 그리는 histogram in R (0) | 2021.12.02 |
고등교육기관 학교급별 신입생 충원율 - 스파게티 선 그래프 in R (5) | 2021.11.27 |
댓글