-
ggplot2 : R 시각화R 이모저모 2019. 6. 10. 19:06
ggplot2를 활용한 시각화
이번 포스팅에서는 R에서 가장 보편적으로 쓰이는 시각화 툴 중 하나인 ggplot2에 대해서 다뤄보고자 합니다. 비록 ggplot2가 속도면에서 문제가 있어 다른 대안을 찾는 추세긴 하나, 여전히 쉽고 강력한 리포팅 기능을 자랑한다는 점은 부인할 수 없는 만큼 기초를 배워두면 R을 사용하는데 있어 큰 도움이 될 것입니다.
0. ggplot의 구조
ggplot은 비교적 직관적인 구조로 이루어져 있습니다. 먼저 ggplot()이라는 함수로 plot을 선언한 후 안에 aes(aesthetic) 함수를 이용해서 원하는 값(예 : 산점도의 x, y좌표)을 넣습니다. 이 때 직접 데이터를 집어넣어도 되며, ggplot함수에서 데이터를 선언하여 앞으로 쓸 데이터를 지정해줘도 됩니다. 데이터를 선언할 경우, dplyr의 함수들과 유사하게 변수 이름만으로 데이터를 불러올 수 있는 장점이 있습니다. 이후 dplyr의 체인과 유사하게 +를 통해서 원하는 기능을 더해가서 그림을 완성하게 됩니다.
위와 같은 과정을 거쳐 만들어진 ggplot 객체는 list형식으로 저장되며, 이 객체에 + 연산자를 더해서 기능을 추가할 수도 있습니다. 그럼 이제 ggplot에서 자주 쓰이는 5가지 plot형식에 대해 예제를 통해 알아보도록 하겠습니다.
1. Scatter Plot
Scatter Plot(산점도)는 x, y 두 개의 데이터가 필요한 그림으로, ggplot에서는 geom_point를 이용해서 정의합니다. 위 사진에서 든 예시 코드를 실행시키면 다음과 같은 그림이 나오게 됩니다.
여기에 color, 즉 색깔을 변수별로 넣으려면 aes()안에 color = 변수명으로 지정해야합니다.
만약 데이터가 순차적인 것(ex : 시계열 데이터)이라면, 점들을 선으로 이어볼 수도 있을 것입니다. 이때는 위의 그래프 객체 p에 geom_line을 더해서 간단히 그릴 수 있습니다.
위 그래프처럼 하나의 기능이 아닌 두 개의 기능(point와 line)을 붙였을 때, ggplot()함수 부분에서 모든 aes를 정의하지 않고 따로 정의함으로서 다른 색을 입히는 것이 가능합니다. 아래 그래프는 geom_point에는 색깔을 주지 않고 선에만 색깔을 준 그래프입니다.
또한 aesthetic함수 밖에서 색상을 지정할 수 있으며, 이 경우 legend에 나오는 일 없이 수동으로 지정된 색상이 나오게 됩니다.
geom_smooth는 말 그대로 smooth 한 추세선을 그려주며, 기본은 loess 방법을 따라갑니다. 만약 직선 추세선을 얻고 싶다면 method 파라미터를 lm으로 바꿔주면 됩니다.
이 때, 선에 생기는 회색 근사지역을 없애고 싶다면 se 파라미터를 FALSE로 지정하면 됩니다.
geom_text 함수는 그래프에 글자를 추가해주며, 이는 좌표가 일정한 산점도에서 별도의 aesthetic 지정 없이 유용하게 쓸 수 있습니다.
2. Histogram
R에서 히스토그램은 hist 함수를 이용해서 간단히 그릴 수 있으나, ggplot의 geom_histogram을 이용하면 좀 더 깔끔하게 그릴 수 있습니다. 기본적으로 히스토그램은 단변수의 빈도 분포를 나타내기에, aes 부분에 하나의 인풋(x)만을 받게 됩니다.
geom_histogram 함수의 bindwidth파라미터를 조정하면 히스토그램의 간격을 조정할 수 있습니다. 위의 그래프의 bin 간격을 0.1로 조정하면 아래와 같은 그래프가 나옴을 확인할 수 있습니다.
3. Bar plot
바 그래프는 종류별 빈도를 나타내기에 가장 편한 그래프로, 주로 집단별로 수치적 데이터가 얼마나 있는지를 표시할 때 많이 사용합니다. ggplot에선 geom_bar를 사용하여 연출하며, 하나의 변수를 입력할 경우 빈도 기반으로(=히스토그램) 나오게 됩니다.
바 그래프 또한 변수를 기준으로 색칠할 수 있으며, color 옵션을 통해 색칠 시 아래와 같은 그래프가 나오게 됩니다.
여기서 확인할 수 있는 점은, color의 경우 외곽선을 칠한다는 것입니다. 바의 안쪽을 칠하고 싶다면 fill 옵션을 사용하여야 합니다.
위 그림보다 훨씬 깔끔하게 색칠된 그래프를 볼 수 있습니다. 또한 두 그래프에서 보듯 단일 변수 바 그래프에서 색깔 aesthetic을 집어넣을 시 바를 분리해서 색칠하는 식으로 색칠됨을 알 수 있습니다. 이 색칠 방식을 변경하려면 geom_bar의 position 파라미터를 fill이나 dodge로 바꿈으로서 해결할 수 있습니다.
2가지 변수를 넣는 경우, y변수를 x변수 기준으로 통합하여 바 그래프를 그리며, 이 때 geom_bar의 stat을 identity로 설정해줘야만 합니다.
4. density plot
밀도 그래프는 1차원과 2차원이 있으며, 1차원의 경우 geom_density 함수를 이용해서 구현할 수 있습니다. 이 때 밑(y = 0)에 불필요한 선이 그려지는데, 이를 지우고 싶다면 geom_line을 이용해서 그리면 간단히 해결할 수 있습니다.
2차원 밀도의 경우 흔히 말하는 contour plot과 동일하며, 어느 곳에 두 변수가 밀집되어 있는지를 표현해주는 그래프입니다. geom_density2d를 활용하여 그릴 수 있습니다.
실제 점 분포와 밀도 그래프를 같이 보고 싶다면 위 그래프에 geom_point를 이용해서 산점도를 추가하는 것으로 볼 수 있습니다.
위의 그림에서 보다시피 실제로 점이 모여있는 곳에 그래프가 형성됨을 알 수 있습니다.
5. Boxplot
박스플랏은 그룹별 한 연속변수의 평균, 4분위, 최소/최대값의 차이를 보기 위해 그리며, geom_boxplot을 이용해서 그릴 수 있습니다.
여타 그래프와 같이, color aesthetic을 활용해서 색깔을 입혀줄 수 있습니다.
6. 테마와 라벨
지금까지 기본적인 plot들의 형태에 대해 알아보았습니다. 이제 만들어진 그래프를 좀 더 예쁘게 꾸미는 방법인 테마와, 제목을 붙여주는 라벨에 대해서 알아보겠습니다. 먼저 전체 그래프 테마의 경우 theme_~로 시작하는 여러 함수들로 제공되며, 제가 자주 사용하는 테마는 theme_bw입니다.
다음으로 그래프의 제목을 붙여보겠습니다. ggplot은 labs혹은 ggtitle 함수로 제목을 넣을 수 있으며, 저는 ggtitle로 넣어보겠습니다. ggtitle은 메인 제목과 서브 제목으로 나눠서 구성할 수 있으며, 아래와 같은 결과가 나오게 됩니다.
위와 비슷한 원리로, x축과 y축의 제목 또한 변경할 수 있습니다. xlab은 x축, ylab은 y축의 제목을 담당하는 함수입니다.
위와 같은 간단한 그래프의 경우 제목이 잘 보이지만, 복잡한 그래프거나 다른 사정으로 그래프의 어떤 요소를 지우고 싶을 수도 있습니다. 이 경우 theme함수의 여러 파라미터를 사용해서 지울 수 있으며, 방법은 원하는 요소 = element_blank()입니다. 예를 들어 축의 제목을 지우고 싶다면 아래와 같이 axis.title = element_blank()로 설정하면 됩니다.
마찬가지로 tick(눈금)을 없애고 싶다면 axis.ticks, x축의 글자들만 없애고 싶다면 axis.text.x를 지정해주면 됩니다.
그렇다면 만약 그래프 범례를 제거하고 싶다면 어떤 작업을 해야할까요? 이 때는 약간 특이하게 legend.position = 'none'으로 지정해주어야합니다.
물론, theme 함수는 단순히 요소를 지우는 것으로만 쓰는 것은 아닙니다. 글자의 경우 element_text함수를 이용해서 여러 속성을 지정해 줄 수 있는데, 예를 들어 그래프의 제목을 볼드체로 바꾸고 싶다면 plot.title = elemt_text(face = 'bold')로 지정하여 바꿀 수 있습니다.
7. coord : Coordinate system
ggplot은 그래프의 구조를 쉽게 반전시키기 위해서 coordinate system을 coord_함수로 제공합니다. 예를 들어, 위 그래프의 x축과 y축을 서로 바꾸고 싶다면 coord_flip 함수를 사용하여 바꿀 수 있습니다.
coord_polar는 이름 그대로 그래프를 원형배치로 바꿔주는 함수로, 파이차트, 스파이더 차트 등을 생성할 때 유용하게 사용할 수 있습니다.
coord_cartesian은 x와 y의 범위를 지정해줄수 있는 함수로, 그래프의 특정 부분만 제한하여 보고 싶을 때 유용하게 사용할 수 있습니다.
8. Facet
facet은 범주형 변수를 기준으로 그래프를 쪼개주는, 일종의 par기능을 해주는 함수입니다. ggplot의 facet이 par보다 더 유용한 점은 하나의 그래프 제목과 범례 안에 여러 그래프를 담을 수 있다는 점입니다. facet_grid 함수는 lm이나 기타 표현식을 받는 함수들과 동일하게 y ~ x 형식으로 사용 가능하며, ~y를 할 경우 칼럼단위로 나눠진 그래프를, y~.를 할 경우 행 단위로 나누어진 그래프를 출력합니다.
언뜻 보기에 굉장히 편한 기능이지만, 단점은 위에서 보다시피 facet으로 나눠진 축은 하나의 축값만 제공해준다는 것입니다. 예를 들어, 아래와 같이 그룹별로 편차가 굉장히 심한 데이터(생성된 df는 g가 a인 경우 {50 ~ 200, 3~5}, b인 경우 {1 ~ 20, 10 ~ 70}, c인 경우 {500 ~ 2000, 0.5 ~ 1.2}로 x,y값의 편차가 그룹별로 매우 크다.)의 경우, 다른 y축을 써야하지만 facet_grid는 그 기능을 제공하지 않고 있는 것을 볼 수 있습니다.
위와 같은 경우 facet_wrap을 한 후 scales = 'free' 옵션을 사용하여 간단히 표현할 수 있습니다. (원래 facet_grid도 제공해야하나 무슨 이유에서인지 작동하지 않음)
9. Coloring
지금까지 본 예제들은 거의 다 색깔을 변수, 그것도 범주형 변수로 지정한 경우였습니다. 만약 연속형 변수로 색깔을 지정하면 어떻게 될까요? 답은 gradient(스펙트럼 형식)한 색깔로 칠해진다 입니다.
위와 같이 aesthetic으로 지정된 색깔이 맘에 들지 않을 경우, scale_color_manual 함수를 이용하여 수동으로 바꿔줄 수 있습니다.
혹은 미리 설정된 여러 palette를 가져와서 사용하는 방법이 있는데, 이 경우 scale_color_brewer함수를 사용합니다.
앞서 설명한 gradient한 색상 또한 조정할 수 있으며, 낮은 쪽과 높은 쪽의 색상만 조정하는 scale_color_gradient 함수와, 중간 색상도 조정가능한 scale_color_gradient2가 있습니다. 2번째 함수는 mid, midpoint를 사용하여 중간지점 설정 및 중간 색상 설정이 가능합니다.
10. Shape
당연하게도, ggplot에서는 점의 모양이 변경 가능합니다. aesthetic에 넣을 경우 변수에 따라 정해진 preset대로, 밖에 넣을 경우 0 ~ 25번에 설정된 모양대로 변경됩니다.
11. Size와 alpha
ggplot은 size와 alpha라는 인풋 또한 제공합니다. size는 말 그대로 해당 기능으로 나오는 그림의 크기를, alpha는 투명도를 나타냅니다. 예를 들어 geom_point에 size와 alpha를 조절할 시 아래와 같은 그림이 나오게 됩니다.
번외. stat_ellipse로 원그리기
군집 분석을 한 후, 해당 군집변수로 묶인 지역을 나타내고 싶을 때 사용할 수 있는 테크닉으로 stat_ellipse가 있습니다. 아래 그래프의 경우 별다른 군집화 없이 Species 기준으로 나누어 겹치는 부분이 많으나, 군집분석을 통해 잘 나누어진 데이터에 적용하면 보다 깔끔한 그래프를 얻을 수 있습니다.
마치며
ggplot은 분명 유용한 시각화 도구이나, ggplot에 맞는 데이터 형식이 있기 때문에 적절한 사용을 위한 데이터 정제가 없다면 만들기까지 매우 느리고 완성되도 지저분한 그림이 될 가능성이 높습니다. 그렇지만 위 11+@의 그래프들을 잘 확인해보고 실제 데이터로 연습한다면, 대부분의 실무 니즈에 맞는 시각화 능력을 갖출 수 있을 것입니다.
[컨텐츠 코드]
'R 이모저모' 카테고리의 다른 글
웹 크롤링 기초와 R (0) 2019.07.21 R로 위키 빌보드 차트 가져오기 (0) 2019.06.23 R과 네트워크 분석(2) (0) 2019.05.29 R과 네트워크 분석 (1) (0) 2019.05.12 Shiny : 대시보드 배포하기 (7) 2019.04.24