여러 그래프 한 번에 나타내기의 필요성
결과 비교를 목적으로 한 그래프를 그릴 때, 여러 상황의 그래프를 한 번에 나열하는 것이 효율적이다.
예시의 논문 (Qian과 Murphy, 2011) 그림처럼 말이다. 확실히 깔끔하다.
논문은 다른 연구자/에디터에게 내 결과를 설득시키고 인정 받아야하는 하나의 글이기 때문에, 내 발견의 노벨티 그 자체도 중요하지만 자신의 결과를 잘 전달하는 것도 중요하다.
그러니 각 그래프를 하나씩 캡쳐해서 짜집기 할 순 없다.
R 코드 - 기본
여러 그래프를 한 번에 나타내주는 par() 라는 함수가 이미 R에 내장되어 있지만 ggplot에선 적용되지 않기 때문에 나는 잘 사용하진 않는다.
그리고 위의 논문 그래프처럼 대제목(전체 그래프에 대한 제목) 만들거나 전체 그래프에 대한 범례 옵션은 없는 것 같다. (글쓴이 추측)
내가 자주쓰는 패키지는 gridExtra 패캐지의 grid.arrange()이다.
임의로 작성한 데이터인데, 아래의 형태로 되어 있는 것이 그래프 그리기 편하다.
Example1에서는 A 방법이 잘 하고 Example2에서는 B방법이 더 잘하는 가상의 결과를 갖는 데이터셋을 생성하였다.
grid.arrange()는 아래의 코드처럼 간단하게 작성되며, ncol과 nrow 옵션을 통해 분할하려는 수 조정이 가능하다.
results <- data.frame("Example" = c("1","1","2","2", "1","1","2","2"),
"N" = c("100", "200", "100", "200", "100", "200", "100", "200"),
"Method" = c("A","A","A","A", "B","B","B","B"),
"Accuracy" = c(0.98, 0.9, 0.8, 0.7, 0.95, 0.84,0.92,0.88))
tmp1 <- results[results$Example==1, ]
tmp2 <- results[results$Example==2, ]
theme_set(theme_bw())
g1 <- ggplot(data=tmp1) + geom_point(aes(x=N, y=Accuracy, shape=Method, color=Method)) + ggtitle("Example 1")
g2 <- ggplot(data=tmp2) + geom_point(aes(x=N, y=Accuracy, shape=Method, color=Method)) + ggtitle("Example 2")
grid.arrange(g1, g2, ncol=2)
R코드 - 옵션 조정
그래프를 합쳤다! 하지만 이게 끝은 아니다.
예시로 든 논문의 그래프는 example 마다 y축이 달라지는 그래프지만,
이 포스팅에서 직접 생성한 예제 데이터의 경우 y축이 Accuracy 이다. Accuracy의 경우 example에 상관없이 항상 0과 1 사이를 갖는데, 함께 나열한 그래프지만 y축의 눈금이 다르면 처음 보는 사람들은 오해할 수 있다.
또한 중복되는 정보를 없애고, 부족한 설명을 채워주어야 한다.
간단하게 몇 가지 세부 옵션들을 조정해보자.
1. 범례 합치기
extract_legend 라는 함수를 새로 정의해준다. 이 함수는 참고자료 2번에서 그대로 가져온 함수이다.
기존에 범례(legend)가 있는 그래프에서 범례를 추출해주는 함수이다.
추출이 끝났다면 범례가 없는 그래프를 새로 만들어준다. (theme 함수의 legend.position = "none")
(주의)
이 방식으로 생성된 legend의 경우 grid.arrange()에서 기존의 g1, g2 처럼 하나의 공간을 차지한다.
그래서 추출된 범례 shared_legend를 g1, g2 와 같은 파라미터로 넣어야 하므로 ncol = 3 이 된다.
shared_legend를 통해 범례를 따로 생성하였으므로, 최종 grid.arrange 에서 사용되는 그래프는 범례가 없는 그래프이다.
범례는 그래프가 아니므로, 그래프와 같은 크기를 차지하지 않도록 너비 파라미터를 조정할 수 있다. (widths= c(3,3,1))
extract_legend <- function(my_ggp) {
step1 <- ggplot_gtable(ggplot_build(my_ggp))
step2 <- which(sapply(step1$grobs, function(x) x$name) == "guide-box")
step3 <- step1$grobs[[step2]]
return(step3)
}
shared_legend <- extract_legend(g1)
g1 <- ggplot(data=tmp1) + geom_point(aes(x=N, y=Accuracy, shape=Method, color=Method)) + ggtitle("Example 1") + theme(legend.position="none")
g2 <- ggplot(data=tmp2) + geom_point(aes(x=N, y=Accuracy, shape=Method, color=Method)) + ggtitle("Example 2") + theme(legend.position="none")
grid.arrange(g1, g2, shared_legend, ncol=3, widths=c(3,3,1))
2. 그래프 제목, x축과 y축 제목 설정
패키지 | 함수 혹은 옵션 | 설명 |
ggplot2 | ggtitle() | 그래프의 제목을 정하는 함수 |
xlab(), ylab() | 축의 제목을 정하는 함수 | |
gridExtra | top = | grid.arrange 함수에서 그래프 위에 글을 삽입하는 옵션 |
bottom = | grid.arrange 함수에서그래프 아래에 글을 삽입하는 옵션 |
grid.arrange에서 요악된 정보를 한 번에 제시할 수 있다.
grid.arrange에서는 top = 과 bottom = 옵션을 통해, 그래프 전체에 대한 설명을 추가할 수 있는 옵션이 있어 편리하다.
g1 <- ggplot(data=tmp1) + geom_point(aes(x=N, y=Accuracy, shape=Method, color=Method)) + ggtitle("Example 1") + xlab("") + ylab("Accuracy") + theme(legend.position="none")
g2 <- ggplot(data=tmp2) + geom_point(aes(x=N, y=Accuracy, shape=Method, color=Method)) + ggtitle("Example 2") + xlab("") + ylab("") + theme(legend.position="none")
grid.arrange(g1, g2, shared_legend, ncol=3, widths=c(3,3,1), top = "Results of simulation", bottom = "sample szie (N)")
3. 눈금 설정
마지막으로 눈금 간격을 설정할 수 있다.
scale_y_continuous(limit=c(0.6, 1.0))는 ggplot에서 그려진 그래프 y축의 의 눈금을 0.6~1.0 사이로 나타내는 함수이다.
마찬가지로 x축에 대해서도 같은 기능을 제공하는 함수가 존재한다.
최종 그래프
g1 <- ggplot(data=tmp1) + geom_point(aes(x=N, y=Accuracy, shape=Method, color=Method)) + ggtitle("Example 1") + xlab("") + ylab("Accuracy") + theme(legend.position="none") + scale_y_continuous(limit=c(0.6, 1.0))
g2 <- ggplot(data=tmp2) + geom_point(aes(x=N, y=Accuracy, shape=Method, color=Method)) + ggtitle("Example 2") + xlab("") + ylab("") + theme(legend.position="none") + scale_y_continuous(limit=c(0.6, 1.0))
grid.arrange(g1, g2, shared_legend, ncol=3, widths=c(3,3,1), top = "Results of simulation", bottom = "sample szie (N)")
참고자료
1. girdExtra
https://cran.r-project.org/web/packages/egg/vignettes/Ecosystem.html
2. 범례 합치기 (링크에서 2번째꺼 사용)
https://statisticsglobe.com/add-common-legend-to-combined-ggplot2-plots-in-r/
'R Programming > Data Visualization' 카테고리의 다른 글
[R] ggplot2 테마 적용으로 쉽게 그래프 꾸미기 (1) | 2023.11.02 |
---|---|
[R] ggplot 수직선, 수평선 그리기: vline, hline (0) | 2023.10.11 |
[R] 이중 축 그래프 그리기: ggplot2, sec_axis 생성 (0) | 2023.10.08 |
[R] Useful Links for ggplot2 (0) | 2023.09.23 |
[R] for 문으로 그래프 생성: ggplot2, for, assign, paste (0) | 2022.08.07 |