R 조금 더 정확하게는 ggplot2 패키지로 그래프를 그리다 보면 마음에 드는 색깔을 골라서 항목을 칠하고 그 색깔을 계속 유지하고 싶을 때가 있습니다.
예컨대 요일별 데이터를 다룰 일이 있다면 토요일은 파랑, 일요일은 빨강으로 고정하면 직관적으로 이해하는 데 도움을 받을 수 있을 겁니다.
이번 포스트에서는 프로야구 각 팀 대표색으로 그래프를 칠하고 그 색깔을 계속 유지하는 연습을 해보겠습니다.
이 포스트를 통해 이 블로그를 처음 찾은 분께 말씀드리면 프로야구 데이터를 활용해 연습하는 게 이 블로그 전통(?)입니다.
자, 그럼 이제 본격적으로 시작해 보겠습니다.
늘 그렇듯 제일 먼저 할 일은 물론 tidyverse 패키지 (설치하고) 불러오기.
#install.packages('tidyverse')
library('tidyverse')
## -- Attaching packages ------------------------- tidyverse 1.3.0 --
## √ ggplot2 3.3.0 √ purrr 0.3.4 ## √ tibble 3.0.1 √ dplyr 0.8.5 ## √ tidyr 1.1.0 √ stringr 1.4.0 ## √ readr 1.3.1 √ forcats 0.5.0
## -- Conflicts ---------------------------- tidyverse_conflicts() -- ## x dplyr::filter() masks stats::filter() ## x dplyr::lag() masks stats::lag()
이어서 지난해(2019년) 각 구단 팀 OPS(출루율+장타력)로 데이터 프레임을 만들어 ops라는 변수에 넣어놓겠습니다.
tribble(
~팀, ~ops,
'키움', .768,
'NC', .762,
'두산', .745,
'KT', .729,
'삼성', .718,
'SK', .718,
'LG', .711,
'KIA', .706,
'한화', .686,
'롯데', .674
) -> ops
물론 잘 들어갔겠지만 혹시 모르니 확인 전화를 한 통 넣어봅니다.
ops
## # A tibble: 10 x 2 ## 팀 ops ## <chr> <dbl> ## 1 키움 0.768 ## 2 NC 0.762 ## 3 두산 0.745 ## 4 KT 0.729 ## 5 삼성 0.718 ## 6 SK 0.718 ## 7 LG 0.711 ## 8 KIA 0.706 ## 9 한화 0.686 ## 10 롯데 0.674
이제 팀별 OPS 막대 그래프를 그려봅니다. 팀별로 막대 색깔을 달리하겠습니다.
ggplot(data=ops, aes(x=팀, y=ops, fill=팀)) +
geom_bar(stat='identity')
다들 잘 아시는 것처럼 따로 색을 지정하지 않으면 ggplot2는 이렇게 내장 기본 팔레트에 따라 색깔을 선택합니다.
이 포스트를 찾아오신 분이라면 ggplot2 기본 문법은 알고 계실 거라고 믿습니다.
그래도 혹시 저 위에 있는 코드가 무슨 뜻인지 모르겠다고 생각하시는 분이 계시면 '최대한 친절하게 쓴 R로 그래프 그리기(feat. ggplot2)' 포스트가 도움이 될 수 있습니다.
이제 색을 바꿔 보겠습니다.
ggplot에서 따로 원하는 색을 지정하고 싶을 때는 scale_fill_manual() 함수를 쓰시면 됩니다.
이번에는 그래프 속을 칠하는(fill) 연습이라 scale_fill_manual()입니다.
만약 color 속성을 바꾸고 싶으실 때는 scale_color_manual()을 쓰시면 됩니다.
아이유 '팔레트' 뮤직 비디오 중에서. 유튜브 캡처
이 함수는 'scale_color_manual(values=팔레트)' 형태로 씁니다.
팔레트를 만들려면 색이 여러 개 필요하겠죠?
우리가 원하는 프로야구 각 팀 대표 색은 이 위키피디아 틀에서 확인할 수 있습니다.
색깔을 확보했으면 팔레트 자체를 만드는 방법은 간단합니다.
'항목 이름'='색깔' 형태로 그냥 주욱 이어 붙이기만 하면 되거든요.
c('두산'='#131230',
'롯데'='#002955',
'삼성'='#074ca1',
'키움'='#7c0022',
'한화'='#ff6600',
'KIA'='#c70125',
'KT'='#000000',
'LG'='#c30452',
'NC'='#315288',
'SK'='#ff0000') -> kbo_palette
이번에도 잘 들어갔는지 안부 전화 한통.
kbo_palette
## 두산 롯데 삼성 키움 한화 KIA KT LG ## "#131230" "#002955" "#074ca1" "#7c0022" "#ff6600" "#c70125" "#000000" "#c30452" ## NC SK ## "#315288" "#ff0000"
그냥 '짝 맞추기'를 한 거니까 이 팔레트 자체는 사실 특이할 게 없습니다.
아, 역시나 혹시 모르시는 분이 계실까 봐 말씀드리면 여기 나온 이상한 숫자+문자 조합은 '웹 색상'이라는 녀석입니다.
문자 그대로 웹 사이트를 만들 때 색깔을 쓰는 방식으로 16진법 숫자 3개를 조합한 겁니다.
이 링크를 클릭하시면 원하는 색깔을 이 형태로 어떻게 표현하는지 확인하실 수 있습니다.
위에서 'scale_fill_manual(values=팔레트)' 형태로 쓴다고 했으니까 우리가 원하는 코드는 'scale_fill_manual(values=kbo_palette)'가 될 겁니다.
위에서 쓴 코드에 이 한 줄을 붙여 보겠습니다.
ggplot(data=ops, aes(x=팀, y=ops, fill=팀)) +
geom_bar(stat='identity') +
scale_fill_manual(values=kbo_palette)
어쩐지 못 생긴 느낌적인 느낌이지만 일단 각 팀 대표색으로 그래프를 칠하는 데는 성공했습니다.
이렇게 팔레트를 지정하면 항목 숫자가 바뀌어도 계속 색을 유지할 수 있습니다.
그게 무슨 뜻인지 한 번 확인해 볼까요?
이번에는 비교하기 쉽게 그래프를 붙여서 그릴 겁니다.
이럴 때는 'patchwork' 패키지를 사용하시면 좋습니다.
당연히 먼저 이 패키지를 (설치하고) 불러옵니다.
#install.packages('patchwork')
library('patchwork')
그다음 자료에서 홀수행만 골라내서 그래프를 그린 다음 p1이라는 변수에 넣겠습니다.
ggplot(data=ops %>% filter(row_number()%%2==1),
aes(x=팀, y=ops, fill=팀)) +
geom_bar(stat='identity') -> p1
마찬가지 방법으로 짝수행만 골라내 p2라는 변수에 넣었습니다.
ggplot(data=ops %>% filterrow_number()%%2==0),
aes(x=팀, y=ops, fill=팀)) +
geom_bar(stat='identity') -> p2
그다음 이 두 그래프를 옆으로 나란히 그리면 이렇게 나타납니다.
p1+p2
양쪽 그래프 색깔 순서가 똑같습니다. 그러니까 ggplot2는 기본적으로 색을 처음부터 다시 지정합니다.
그나저나 patchword 패키지 정말 편하지 않나요?
그냥 p1+p2라고 썼을 뿐인데 그래프를 옆으로 나란히 그렸습니다.
이 패키지를 조금 더 알아보고 싶으시면 'ggplot2 그래프 이어 붙이기(feat. patchwork)' 포스트를 읽어 보셔도 좋습니다.
또 '파이프(%>%)' 기호가 등장하고, filter() 함수가 나타나 당황한 분이 계실지도 모르겠습니다.
이런 분들은 '최대한 친절하게 쓴 R로 데이터 뽑아내기(feat. dplyr)'를 읽어보시면 도움이 될 수 있을 겁니다.
다시 본론으로 돌아가서 팔레트를 썼을 때 어떤 상황이 되는지 알아보겠습니다.
이번에는 홀수행만 골라내서 팔레트를 적용한 그래프를 p3,
ggplot(data=ops %>% filter(row_number()%%2==1),
aes(x=팀, y=ops, fill=팀)) +
geom_bar(stat='identity')+
scale_fill_manual(values=kbo_palette) -> p3
그리고 짝수행만 골라내서 역시 팔레트를 적용한 그래프를 p4에 넣겠습니다.
ggplot(data=ops %>% filter(row_number()%%2==0),
aes(x=팀, y=ops, fill=팀)) +
geom_bar(stat='identity') +
scale_fill_manual(values=kbo_palette) -> p4
그리고 patchwork 스타일로 그래프를 그리면
p3+p4
이번에는 팔레트 색깔을 그대로 유지하고 있는 걸 확인할 수 있습니다.
그래서 '항목 이름'='색깔' 형태로 팔레트를 지정하는 겁니다.
고생 많으셨습니다. 원래 처음 우리가 이 포스트에서 연습해 보려고 했던 건 이제 끝났습니다.
이제부터는 그냥 이미 그래프를 그린 게 아까워 쓰는 보너스입니다.
'최대한 친절하게 쓴 R로 그래프 그리기(feat. ggplot2)' 포스트에서도 말씀드렸던 것처럼 순위를 그래프로 나타낼 때는 세로 방향으로 그래프를 그리는 게 기본입니다.
ggplot2에서는 coord_flip() 함수를 써서 이 작업을 진행할 수 있습니다.
그냥 우리가 위에서 그래프를 그릴 때 쓴 코드에 coord_flip() 한 줄만 추가하면 됩니다.
ggplot(data=ops, aes(x=팀, y=ops, fill=팀)) +
geom_bar(stat='identity') +
scale_fill_manual(values=kbo_palette) +
coord_flip()
기왕이면 OPS가 높은 팀부터 낮은 팀 순서로 그리면 더 보기가 좋겠죠?
이럴 때는 reorder() 함수를 써서 x축(팀 이름) 순서를 정렬하면 됩니다.
위에 있는 그래프에서는 팀 이름이 y축에 있는 x축 순서를 바꾼다고 말씀드린 건 coord_flip() 함수는 겉으로 보기에만 축을 바꾸기 때문입니다.
reorder() 함수는 기본적으로 reorder(바꾸고 싶은 항목, 기준) 순서로 쓰시면 됩니다.
우리는 팀 이름을 ops 순서에 따라 정렬하고 싶은 거니까 reorder(팀, ops) 형태입니다.
이렇게 정리한 코드를 x축을 지정하는 부분에 넣으면 끝입니다.
ggplot(data=ops, aes(x=reorder(팀, ops), y=ops, fill=팀)) +
geom_bar(stat='identity') +
scale_fill_manual(values=kbo_palette) +
coord_flip()
참고로 tidyverse 생태계에도 이렇게 카테고리(factor) 정리를 도와주는 forcats 패키지가 있습니다.
이 패키지 가운데 fct_reorder() 함수가 reorder()와 같은 방법으로 작동합니다.
ggplot(data=ops, aes(x=fct_reorder(팀, ops), y=ops, fill=팀)) +
geom_bar(stat='identity') +
scale_fill_manual(values=kbo_palette) +
coord_flip()
이렇게 그래프를 그리고 나니 뭐 거슬리는 거 없으십니까?
저는 오른쪽에 있는 범례(legend)가 거슬렸습니다. 그래프 순서하고 맞지 않으니까요.
이 범례 순서를 정렬하는 방법도 x축 항목 정렬과 똑같습니다.
그저 현재 x축이 내림차순 정렬 상태라 기준 변수에 마이너스(-) 부호만 붙여주면 그만입니다.
ggplot(data=ops, aes(x=fct_reorder(팀, ops), y=ops, fill=fct_reorder(팀, -ops))) +
geom_bar(stat='identity') +
scale_fill_manual(values=kbo_palette) +
coord_flip()
이렇게 하고 났더니 (별로 필요한지는 잘 모르겠지만) 범례와 그래프가 같은 순서로 나타났습니다.
그런데 범례 이름이 'fct_reorder(팀, -ops)'로 나와 있으니 역시 또 거슬립니다.
'R에서 묶은 막대 그래프에 레이블 쓰기(feat. poistion_dodge)'에서 설명해 드린 것처럼 이럴 때는 scale_fill_manual() 함수 안에 name 속성을 바꾸면 그만입니다.
원래대로 '팀'이라고 바꾸려면 그냥 name='팀'이라고 덧붙이면 됩니다.
ggplot(data=ops, aes(x=fct_reorder(팀, ops), y=ops, fill=fct_reorder(팀, -ops))) +
geom_bar(stat='identity') +
scale_fill_manual(values=kbo_palette, name='팀') +
coord_flip()
예, 의도했던 대로 바뀌었습니다.
사실 그래프에서는 이런 범례가 큰 의미가 있다고 하기 어렵습니다.
그래도 ggplot2에서 범례 순서를 어떻게 바꾸는지 알아 둔다고 해서 손해보실 일은 없을 겁니다.
이대로 포스트 작성을 끝내려고 했는데 이제는 축 제목이 거슬립니다.
x축 제목을 바꿀 때는 xlab(), y축 제목을 바꿀 때는 ylab()입니다.
ggplot(data=ops, aes(x=fct_reorder(팀, ops), y=ops, fill=fct_reorder(팀, -ops))) +
geom_bar(stat='identity') +
scale_fill_manual(values=kbo_palette, name='팀') +
xlab('팀') + ylab('OPS') +
coord_flip()
모쪼록 ggplot2 그래프 색깔을 바꾸고 싶은데 못 하고 계셨거나, 범례 순서를 어떻게 바꾸는지 몰라서 애태우셨던 분들께 도움이 되었기를 바랍니다.
그럼 모두들 Happy Charting!
댓글,