聰明不如鈍筆
총명불여둔필
assignment KindeR

R로 롤리팝, 덤벨, 슬로프 차트 그리기(feat. geom_point, geom_segment)


롤리팝(lollipop), 덤벨(dumbell), 슬로프(lope) 차트는 이름은 서로 다르고 쓰임새도 다르지만 코딩 관점에서 보면 삼란성(?) 쌍둥이라고 할 수 있습니다.


R에서, 조금 더 정확하게는 ggplot2 패키지를 써서 이 세 가지 그래프를 그릴 때는 geom_point() 그리고 geom_segment() 함수만 잘 활용하면 됩니다.


이미 이렇게만 써도 힌트를 얻어 이 포스트를 닫고 R 화면으로 이동한 분이 계실 거라고 예상할 수 있을 정도로 작업은 간단합니다. 그저 단순 반복 작업일 뿐이니까요.


아, 이 포스트는 데이터 처리 과정에서 tidyverse 문법을 사용합니다. 이 문법에 익숙하지 않은 분은, 그래프를 그리는 과정에서는 크게 중요한 부분은 아니지만, 데이터를 처리하는 과정을 이해하시기가 어려울 수 있습니다.


이런 분에게는 '최대한 친절하게 쓴 R로 데이터 뽑아내기(feat. dplyr)', '최대한 친절하게 쓴 R로 데이터 깔끔하게 만들기(feat. tidyr)' 포스트가 도움이 될 수 있습니다. ggplot2 기초 사용법이 궁금하신 분은 '최대한 친절하게 쓴 R로 그래프 그리기(feat. ggplot2)'를 먼저 읽고 오셔도 좋습니다.


.

.

.

.

.

.

.

.

.

.


여기까지 스크롤을 내리셨다는 건 이제 이 포스트를 (다시) 떠날 필요가 없다는 뜻일 테니 이번 연습에 쓸 데이터를 공개하겠습니다. 아래 있는 CSV 파일은 프로배구 2018~2019 V리그 남녀부 구단 공격 유형별 시도 횟수를 정리한 내용을 담고 있습니다.


kovo_sets.csv


노파심에 말씀드리면 CSV는 'Comma Separated Value(쉼표로 구분한 값)'를 줄인 말로, CSV 파일은 기본적으로 데이터 열 사이를 쉼표로 구분한 텍스트 형태입니다. 그런 이유로 '메모장'이나 마이크로소프트(MS) 엑셀 등에서 파일 내용을 확인할 수 있으며 물론 R에서도 이런 파일을 열 수 있습니다.


파일을 컴퓨터에 내려받으신 다음 R 콘솔에 다음처럼 입력하시고, 이어 나오는 파일 선택창에서 내려받은 파일 위치를 지정해 주시면, 'kovo'라는 변수에 파일 내용을 저장하고, 내용까지 확인하실 수 있습니다.

kovo <- read.csv(file.choose())
kovo
##    남녀부        구단 오픈 속공 퀵오픈 시간차 이동 후위
## 1      남  현대캐피탈 1192  555    687     59    0  832
## 2      남    대한항공 1094  537   1103     46    2  864
## 3      남    우리카드 1417  353    812     61    0  737
## 4      남    삼성화재 1552  387    490     57   16  901
## 5      남  OK저축은행 1156  420    738    128    1  799
## 6      남  KB손해보험 1249  411    812    110    3 1037
## 7      남    한국전력 1306  460    927    106    3  790
## 8      여    흥국생명 2397  257    734    228  135  547
## 9      여    도로공사 2288  326   1059    206  186  391
## 10     여    GS칼텍스 2138  314   1113    107   27  469
## 11     여 IBK기업은행 2419  229    939    210  117  484
## 12     여    현대건설 2442  313    643    127   21  521
## 13     여 KGC인삼공사 2066  251   1003    224   91  377


아, 숙제가 하나 더 있습니다. 아직 tidyverse 패키지를 설치하지 않으셨다면 이 패키지를 설치하고 불러들이는 과정이 필요합니다. tidyverse 패키지를 설치한다는 건 사실 △dplyr △forcats △ggplot2 △purrr △readr △stringr △tibble △tidyr 등 8개 패키지를 설치한다는 뜻입니다. R를 계속 쓰시게 된다면 언젠가 모두 필요하게 될 패키지니까 이번 기회에 설치하시는 것도 나쁘지 않을 겁니다. 물론 하나씩만 설치하시는 것도 가능합니다.


R에서 패키지를 설치할 때는 install.packages()라는 명령어를 쓰고, 이를 메모리에 불러들이는 건 library()입니다. tidyverse 패키지를 설치하고 불러들이는 건 이렇게 쓸 수 있습니다.

install.packages('tidyverse')
library('tidyverse')


서론이 길었습니다. 이제 본격적으로 그래프를 그려보겠습니다.


롤리팝 차트부터 그려보자


롤리팝 차트는 위에 있는 그림처럼 막대사탕 모양으로 정보를 나타내는 형태. 이런 그래프 한두 번 정도는 다들 보신 적 있을 겁니다. (참고로 'Lorem Ipsum·로렘 입숨'은 디자인 과정에서 '나중에 여기에 글씨를 쓸 예정'이라고 알려주는 문구입니다.)


이 포스트 첫 부분에 말씀드린 것처럼 이 그래프는 그릴 때는 geom_point() 그리고 geom_segment() 함수 두 개만 있으면 됩니다. 이름을 가지고 추측하자면 geom_point()가 사탕 모양 부문을 담당하고 geom_segment()가 막대겠지요?


아래처럼 코드를 쓰면 일단 점과 선으로 각 구단별 퀵오픈 시도 횟수를 나타낼 수 있습니다.

ggplot(kovo, aes(x=구단, y=퀵오픈)) +
  geom_segment(aes(xend=구단, yend=0)) +
  geom_point()


geom_segment()에 익숙하지 않은 분이라면 두 번째 줄을 이해하시기 어려울 수 있습니다. geom_segment()는 기본적으로 한 점과 다른 점 사이를 선으로 연결하는 구실을 하고 기본적으로 이런 형태로 코드를 씁니다.

geom_segment(aes(x=x시작점, xend=x끝점, y=y시작점, yend=y끝점))


그런데 우리가 쓴 코드에는 x시작점, y시작점이 없습니다. 이건 시작점은 이미 첫 줄에 x=구단, y=퀵오픈이라고 쓴 걸로 충분하기 때문입니다. 대신 xend, yend 속성은 해당하는 값이 없으니까 채워준 겁니다. 점을 기준으로 x축까지 직선을 그으면 되니까 xend는 x와 마찬가지로 구단, y는 0이 되는 겁니다. 이해가시죠?


위에 있는 그래프에서 제일 아쉬운 건 일단 점 크기가 사탕이라고 하기엔 너무 작다는 것. 그리고 색깔이 전부 검다는 것도 아쉽습니다. 점 크기를 키우고(size=5), 남녀부에 따라 색깔을 달리해보겠습니다(color=남녀부).

ggplot(kovo, aes(x=구단, y=퀵오픈, color=남녀부)) +
  geom_segment(aes(xend=구단, yend=0)) +
  geom_point(size=5)


이렇게 그리고 나니 결과를 순서대로 보여주고 싶습니다. 이럴 때 가장 일반적인 접근법은 reorder()를 쓰는 겁니다. 우리는 구단을 퀵오픈 순서로 정리하고 싶으니까 'reorder(구단, 퀵오픈)'이라고 쓰면 그만입니다.


이렇게 그리고 나니 남녀부를 따로 그리면 더 좋을 것 같습니다. 이럴 때는 그래프를 분리하는 facet_grid()를 쓰면 됩니다. 옆으로 나누고 나누겠습니다. 이럴 때는 'facet_grid(~남녀부)'라고 쓰면 됩니다. 세로로 나누고 싶을 때는 'facet_grid(남녀부~.)' 형태로 쓰셔야 합니다.

ggplot(kovo, aes(x=reorder(구단, 퀵오픈), y=퀵오픈, color=남녀부)) +
  geom_segment(aes(xend=reorder(구단,  퀵오픈), yend=0)) +
  geom_point(size=5) +
  facet_grid(~남녀부)


잘 나오기는 했는데 각 면(面)에 계속 상대부 구단 이름이 들어 있습니다. 이럴 때는 facet_grid()에 "scales='free_x'"를 더하면 됩니다. 물론 세로일 때는 "scales='free_y'"가 될 겁니다.

ggplot(kovo, aes(x=reorder(구단, 퀵오픈), y=퀵오픈, color=남녀부)) +
  geom_segment(aes(xend=reorder(구단,  퀵오픈), yend=0)) +
  geom_point(size=5) +
  facet_grid(~남녀부, scales='free_x')


애석하게도 구단 이름이 겹치는 문제는 해결하지 못했습니다. 이 문제를 해결하는 가장 손쉬운 방법은 그래프를 세로 형태로 바꾸는 것. 게다가 인포그래픽 관련 고전 'The Wall Street Journal Guide to Information Graphics'는 순서를 나타낼 때는 세로 (막대) 그래프를 쓰라고 추천합니다.


이렇게 그래프를 뒤집을 때는 coord_flip()을 씁니다. 아무 속성도 넣지 않고 coord_flip()만 넣어도 x축과 y축을 바꿉니다. 이렇게 말입니다.

ggplot(kovo, aes(x=reorder(구단, 퀵오픈), y=퀵오픈, color=남녀부)) +
  geom_segment(aes(xend=reorder(구단,  퀵오픈), yend=0)) +
  geom_point(size=5) +
  coord_flip() +
  facet_grid(남녀부~., scales='free_y')


고생하셨습니다. 이렇게 여러분 첫 롤리팝 차트를 그리는 데 성공했습니다. 이제 세 쌍둥이 중에 첫째가 나왔으니 나머지는 그리 어렵지 않습니다.



덤벨 차트도 그려보자


덤벨 차트에서 덤벨은 아령(啞鈴)이라는 뜻. 참고로 啞는 '벙어리 아', 鈴은 '방울 령'이기 때문에 아령과 영어 낱말 dumbbell은 뜻이 같습니다.


롤리팝 차트는 한쪽이 동그라미고 덤벨차트는 양쪽이 모두 동그라미입니다. 그러면 geom_point()를 두 번 써야겠죠? 당연히 점을 찍을 지점도 두 개가 필요합니다.


한번 공격 유형별 최소·최다 시도 횟수를 그려볼까요? 물론 남녀부를 구분해서 말입니다. 그러면 먼저 유형별 최소·최다 시도 횟수가 몇 번인지 알아야겠죠?


이를 알아보는 방법은 두 가지. 하나는 일일이 숫자를 센 다음에 이런 자료를 담은 변수를 하나 새로 만드는 겁니다. 번거롭겠죠? 그래서 우리는 자동으로 처리하는 두 번째 방법을 쓸 겁니다.


우리는 지금 데이터 정제 과정을 공부하는 건 아니니까 일단 아래 코드를 그냥 Ctrl+C/V 해보세요. 그러면 이렇게 재미있는 결과가 나타납니다. 

kovo %>% 
    gather(종류, 숫자, -남녀부, -구단) %>%
    group_by(남녀부, 종류) %>%
    summarise(최소=min(숫자), 최다=max(숫자))
## # A tibble: 12 x 4
## # Groups:   남녀부 [?]
##    남녀부 종류    최소  최다
##         
##  1 남     속공     353   555
##  2 남     시간차    46   128
##  3 남     오픈    1094  1552
##  4 남     이동       0    16
##  5 남     퀵오픈   490  1103
##  6 남     후위     737  1037
##  7 여     속공     229   326
##  8 여     시간차   107   228
##  9 여     오픈    2066  2442
## 10 여     이동      21   186
## 11 여     퀵오픈   643  1113
## 12 여     후위     377   547


이 코드는 우리가 지금까지 쓰고 있던 kovo라는 변수를 롱 타입 형태로 바꾼 뒤 → 남녀부 & 공격 종류를 기준으로 → 최솟값과 최댓값을 요약해 달라는 뜻입니다.


우리는 지금 데이터 정제 과정을 공부하는 게 아니니까 설명은 이 정도로 넘어갑니다. 어떻게 이런 결과가 나왔는지 궁금하시는 분은 '최대한 친절하게 쓴 R로 데이터 뽑아내기(feat. dplyr)', '최대한 친절하게 쓴 R로 데이터 깔끔하게 만들기(feat. tidyr)' 포스트를 읽어보시면 도움이 될 수 있습니다.


사실 여기까지 작업을 하셨으면 그래프를 다 그리신 거나 마찬가지입니다. 남은 건 실제로 코드를 쓰는 것. 남녀부로 면(面)을 구분한 다음 공격 종류별로 최소, 최다에 해당하는 지점에 점을 찍고 두 점 사이를 연결하면 그만입니다. 기왕 하는 거 위에서처럼 reorder()를 써서 순서도 정리해 보겠습니다. 점 크기는 3.

kovo %>% 
    gather(key=종류, value=숫자, -남녀부, -구단) %>%
    group_by(남녀부, 종류) %>%
    summarise(최소=min(숫자), 최다=max(숫자)) %>%
    ggplot(aes(x=reorder(종류, 최다), y=최다)) + 
        geom_point(size=3) +
        geom_point(aes(y=최소), size=3) +
        geom_segment(aes(xend=reorder(종류, 최다), yend=최소)) +
        coord_flip() +
        facet_grid(남녀부~.)

 

다시 말씀드리면 덤벨 차트를 그릴 때 기본은 최솟값, 최댓값을 확보하는 겁니다. 이런 자료를 만들었다면 먼저 최댓값을 기준으로 점을 찍습니다. 두 번째 점은 나머지는 그대로 두고 y값만 바꿔주면 되니까 geom_point() 안에 'aes(y=최솟값)'을 넣어줍니다.


이어서 geom_segment를 쓰는 요령은 롤리팝 차트와 같습니다. 이번에도 xend에는 x와 같은 값을 넣어주면 그만이지만 yend가 0이 아니라 최솟값이라는 점만 다를 뿐입니다.


중간에 데이터 처리 과정 때문에 헷갈리실 수 있으니 간단한 예를 만들어 덤벨 차트를 하나 더 그려보겠습니다. 아래는 올해 8월 1~9일 서울지역 최저·최고 기온을 정리한 자료입니다.

temperature <- data.frame(날짜=c(1, 2, 3, 4, 5, 6, 7, 8, 9), 
                          최저=c(26.3, 28.4, 29.4, 28.3, 30.5, 31.6, 26.9, 28.9, 29.8),
                          최고=c(30.1, 33.1, 36, 34.4, 35.9, 36.8, 30.3, 32.7, 34.6))
temperature
##   날짜 최저 최고
## 1    1 26.3 30.1
## 2    2 28.4 33.1
## 3    3 29.4 36.0
## 4    4 28.3 34.4
## 5    5 30.5 35.9
## 6    6 31.6 36.8
## 7    7 26.9 30.3
## 8    8 28.9 32.7
## 9    9 29.8 34.6


하번 코드를 차근 차근 써보겠습니다. 맨 처음에는 ggplot이 나오고, 그 안에 aes, 그 안에 x에 '날짜', y에는 일단 '최고'가 와야합니다. 그렇죠?


그다음에는 geom_point()만 하나 쓰면 됩니다. 두 번째 점을 찍을 때는 geom_point() 안에 aes를 쓴 다음 그 안에 y에 '최저'가 온다고 씁니다.


마지막으로 geom_segment()를 쓰면서 xend는 x와 마찬가지로 '날짜', yend에는 '최저'가 오면 됩니다.


지금까지 말씀드린 걸 실제 코드로 쓰면 이렇습니다.


ggplot(temperature, aes(x=날짜, y=최고)) +
    geom_point() +
    geom_point(aes(y=최저)) +
    geom_segment(aes(xend=날짜, yend=최저))


여기까지가 코드 뼈대고 나머지는 취향입니다. 점 크기를 키울 수도 있고 그래프 x, y축을 바꿀 수도 있습니다. 이 정도면 어떻게 하는지 감을 잡으셨을 줄로 믿고 나머지는 연습용으로 남겨 놓겠습니다.



슬로프 차트까지 그려보자


덤벨 차트까지 그리셨으면 슬로프 차트를 그리는 건 어렵지 않습니다. 그냥 기울기(slope)만 조절하면 되니까요. 이번에는 프로배구 남녀부 공격 패턴이 어떤 차이가 있는지 슬로프 차트를 그려보도록 하겠습니다.


그러면 먼저 공격 종류별 점유율을 알아야 합니다. 점유율은 '해당 공격 시도 ÷ 전체 공격 시도'로 계산할 수 있습니다. 이번에도 이를 알아보는 방법은 두 가지. 하나는 일일이 계산해서 데이터를 새로 만든다. 또 하나는 코드를 써서 자동으로 계산하게 만든다. 물론 우리 선택은 코딩입니다. 이렇게 쓰면 원하는 결과를 얻을 수 있습니다.

kovo %>%
  mutate(공격=오픈+속공+퀵오픈+시간차+이동+후위) %>%
    group_by(남녀부) %>%
    summarise(오픈=sum(오픈)/sum(공격),
                속공=sum(속공)/sum(공격),
                퀵오픈=sum(퀵오픈)/sum(공격),
                시간차=sum(시간차)/sum(공격),
                이동=sum(이동)/sum(공격),
                후위=sum(후위)/sum(공격)) %>%
    gather(종류, 비율, -남녀부)
## # A tibble: 12 x 3
##    남녀부 종류      비율
##          
##  1 남     오픈   0.370  
##  2 여     오픈   0.541  
##  3 남     속공   0.129  
##  4 여     속공   0.0665 
##  5 남     퀵오픈 0.230  
##  6 여     퀵오픈 0.216  
##  7 남     시간차 0.0234 
##  8 여     시간차 0.0434 
##  9 남     이동   0.00103
## 10 여     이동   0.0227 
## 11 남     후위   0.246  
## 12 여     후위   0.110


한 번 더 말씀드리자면 이런 결과를 얻은 코드가 이해가 가지 않으시는 분은 '최대한 친절하게 쓴 R로 데이터 뽑아내기(feat. dplyr)', '최대한 친절하게 쓴 R로 데이터 깔끔하게 만들기(feat. tidyr)' 포스트를 읽어보시면 힌트를 얻으실 수 있습니다.


이 자료를 가지고 위에서 말씀드린 슬로프 차트를 그린다면 일단 x축에는 남, 여가 각각 와야 할 겁니다. 그리고 공격 종류에 따라 점을 찍고 선을 그리면 되겠죠? 공격 종류에 따라 색깔에도 차이를 두겠습니다. 위에서 이미 확인한 데이터를 kovo2라는 변수에 넣고 그래프까지.

kovo %>%
  mutate(공격=오픈+속공+퀵오픈+시간차+이동+후위) %>%
    group_by(남녀부) %>%
    summarise(오픈=sum(오픈)/sum(공격),
                속공=sum(속공)/sum(공격),
                퀵오픈=sum(퀵오픈)/sum(공격),
                시간차=sum(시간차)/sum(공격),
                이동=sum(이동)/sum(공격),
                후위=sum(후위)/sum(공격)) %>%
    gather(key=종류, value=비율, -남녀부) -> kovo2

ggplot(kovo2, aes(x=남녀부, y=비율, group=종류, color=종류)) + 
    geom_line() + 
    geom_point()


일단 성공입니다. 공격 종류별 점유율 차이를 숫자로 써넣고 싶을 때는 어떻게 하면 될까요? ggplot 그래프 위에 글씨를 쓰고 싶을 때는 geom_text()를 쓰면 됩니다. 우리가 쓰고 싶은 값은 '비율'입니다. 따라서 'geom(aes(label=비율))'을 덧붙이면 비율값이 나올 겁니다.

ggplot(kovo2, aes(x=남녀부, y=비율, group=종류, color=종류)) + 
    geom_line() + 
    geom_point() +
  geom_text(aes(label=비율))


이런 결과를 기대하셨던 분은 아니 계실 겁니다. 이걸 조금 더 보기 좋게 만들려면 백분율(%) 형태로 바꾸고 소수점 이하 자릿수도 조정해야 할 것 같습니다. 이럴 때 쓰는 함수는 기본적으로 반올림할 때 쓰는 round()입니다.


두 함수 연습 차원에서, 일일이 숫자를 치기 귀찮으니, 0.5413598960589(여자부 오픈 점유율)를 a라는 변수에 넣어 놓겠습니다.

a <- 0.5413598960589


우리는 직관적으로 이 숫자가 약 54.1%에 해당한다는 걸 압니다. R에서 이 숫자를 나타내게 하려면 어떻게 해야 할까요? 국민학교 초등학교 때 배운 것처럼 시작은 숫자에 100을 곱하는 것. 반올림도 필요합니다. 코드는 이렇게 나오겠죠?

round(a*100)
[1] 54


백분율을 표시할 때는 (적어도 저는) 소수점 한 자리 정도는 써주는 게 기본입니다. 그럴 때는 코드를 이렇게 살짝 고쳐주면 됩니다.

round(a*100, 1)
[1] 54.1


그런데 round(0.54*100, 1)을 넣어보시면 54.0이 아니라 54가 나옵니다. 이를 54.0으로 표시하고 싶으실 때는 format() 함수를 쓰시면 됩니다. format 함수는 nsmall 속성에 따라 소수 자릿수를 결정합니다. 최소 한자리는 꼭 표시하라고 하고 싶으면 'nsmall=1'이라고 쓰면 됩니다.

format(round(.54*100, 1), nsmall=1)
[1] "54.0"


이런 형태로 값을 나타내려면 위에 쓴 코드 가운데 geom_text() 안에 'format(round(비율*100, 1), nsmall=1)'를 넣어두면 될 겁니다.

ggplot(kovo2, aes(x=남녀부, y=비율, group=종류, color=종류)) + 
    geom_line() + 
    geom_point() +
  geom_text(aes(label=format(round(비율*100, 1), nsmall=1)))


역시 이번에도 일단 OK. 이제 위치만 바로잡으면 됩니다. 이때 가장 손쉬운 방법은 ggrepel 패키지를 활용하는 것. 이번에는 쉬운 건 연습용으로 남겨두고 정통(?)으로 한번 해결해 보겠습니다.


이 그래프에서 글자 모양을 정리하는 기본 방식이 있다면 남자부는 글씨는 왼쪽으로, 여자부는 오른쪽으로 옮기는 작업일 겁니다. 그럼 남녀부 데이터를 각각 뽑아내려면 어떻게 해야 할까요? tidyverse 생태계를 알고 계시는 분은 filter() 함수를 떠올리셨을 줄로 믿습니다. 모르셨던 분도 함수 이름을 듣고 보니 어쩐지 그럴 것 같으시죠?


남자부만 뽑으려면 filter(남녀부 == '남')이라고 쓰시면 됩니다. R에서 등호(=)는 어떤 값을 변수에 넣으라는 뜻을 '<-'와 같은 뜻이기 때문에 '똑같다'고 할 때는 '=='를 쓴다는 것만 알고 계시면 어려울 게 없습니다. 자연스레 여자부는 filter(남녀부=='여')입니다.


그러면 글씨를 왼쪽으로 옮기려면 어떻게 해야 할까요? R에서 텍스트 정렬(justification)을 조절할 때 가로는 hjust, 세로는 vjust를 씁니다. hjust 뒤에 오는 값이 플러스(+)면 왼쪽, 마이너스(-)면 오른쪽으로 움직입니다.


이를 종합하면 코드로는 이렇게 쓸 수 있습니다.

ggplot(kovo2, aes(x=남녀부, y=비율, group=종류, color=종류)) + 
    geom_line() + 
    geom_point() +
    geom_text(data=kovo2 %>% filter(남녀부=='남'), aes(label=format(round(비율*100, 1), nsmall=1)), hjust=1.2) +
    geom_text(data=kovo2 %>% filter(남녀부=='여'), aes(label=format(round(비율*100, 1), nsmall=1)), hjust=-.2)


이 그래프를 보고 있으니 어떤 색이 어떤 항목인지 쉽게 알 수 있도록 범례가 점 옆에 있으면 더욱 좋겠다는 생각이 듭니다. 양 쪽에 모두 쓸 필요는 없고 남자부 쪽에 써주는 걸로 충분할 듯합니다.


문자를 붙여 쓸 때 쓰는 함수는 paste()입니다. copy & paste할 때 바로 그 paste죠. "aaa"라는 문구와 "bbb"라는 문구를 한번 paste()로 연결해 볼까요?

paste("aaa", "bbb")
[1] "aaa bbb"


우리가 연결하려는 건 종류와 format(), round() 함수로 처리한 비율이니까 paste(종류, format(round(비율*100, 1), nsmall=1)), hjust=1.2))가 될 겁니다. 뒷부분이 복잡해 보여도 그냥 위에서 쓴 코드를 copy & paste한 데 지나지 않습니다.


아, 남자부 점 옆에 종류를 표시한다면 그래프가 계속 그래프 오른쪽에 있을 필요는 없겠죠? 범례를 지우려면 guides(color=FALSE, fill=FALSE)를 코드에 더하시면 그만입니다. 이제 전체 코드는 이렇게 됩니다.

ggplot(kovo2, aes(x=남녀부, y=비율, group=종류, color=종류)) + 
    geom_line() + 
    geom_point() +
    geom_text(data=kovo2 %>% filter(남녀부=='남'), aes(label=paste(종류, format(round(비율*100, 1), nsmall=1))), hjust=1.2) +
    geom_text(data=kovo2 %>% filter(남녀부=='여'), aes(label=format(round(비율*100, 1), nsmall=1)), hjust=-.2) +
    guides(color=FALSE, fill=FALSE)


네, 이 정도면 기본 뼈대로는 나쁘지 않은 형태가 나왔습니다. 이제부터는 취향에 따라 디자인을 하시면 됩니다. 물론 위에 있는 롤리팝, 덤벨 차트도 마찬가지. 멋진 디자인에 성공하셨다면 저한테도 구경시켜 주세요. 그럼 Happy Charting!


댓글,

KindeR | 카테고리 다른 글 더 보기