5 min read

ggplot2 버전 업데이트 리뷰


출처: Tidyverse-ggplot2 3.3.0

ggplot2 3.3.0

ggplot2 가 2020년 3월 5일에 3.3.0으로 업데이트가 되었다. ggplot을 조금 쓰고 있기는 하다만 막상 ggplot전체중 얼마나 쓰고 있냐고 물어보면 5%수준 정도도 안되는 사용향에 이번에 한번, 관심을 가져보고자 포스팅을 해보려 한다. 패키지가 업데이트 되어 install.packages(“ggplot2”) 로 재설치 하면 됬으나, Mac의 경우에는 remove.packages(“ggplot2”)를 진행하고 설치를 다시 했어야 하더라. 그럼 이제 하나씩 추가된 기능을 소개해보도록 하겠다.

X축, Y축의 라벨 겸칩에서 해방

기존 x축을 표현할때 텍스트가 길어지면 겹쳐서, 어쩔수 없이 각도에 변화룰 주어야 했었다. 그러나 이번에 추가된 기능으로는 guide_axis()가 생겼다.

library(ggplot2)
library(patchwork)

p <- ggplot(mpg) +
  geom_bar(aes(x = manufacturer)) + 
  theme(axis.text.x = element_text(size = 11))

# Overlapping labels
plot(p)

label 겹치는 문제 해결

기존 코드에 scale_x_discrete(guide = guide_axis(n.dodge = 2))를 추가 해주어 label의 겹침을 해결 할 수 있다.

# Use guide_axis to dodge the labels
p + 
  scale_x_discrete(guide = guide_axis(n.dodge = 2))

겹치는 label 제거

또는 scale_x_discrete(guide = guide_axis(check.overlap = TRUE)) 코드를 사용하여 겹치는 부분을 제거 할 수 있다.

# Or to remove overlapping labels
p + 
  scale_x_discrete(guide = guide_axis(check.overlap = TRUE))

새로운 scale 의 등장 : scale_*_binned()

**scale_( )_discrete** & **scale_( )_continuous** 에 이은 3번째 scale이 추가 되었다.

p <- ggplot(mpg) + 
  geom_point(aes(displ, cty, size = hwy, colour = hwy))

연속형 데이터에 이산형 크기로 구분 짓기 가능

scale_size_binned()를 사용하면서 연속형데이터인 hwy에 대해 단계적으로 구분을 지어 크기로 표현을 할 수가 있다.

p + 
  scale_size_binned()

연속형 데이터에 이산형 컬러로 구분 짓기 가능

scale_colour_binned()를 사용하면서 연속형으로 표현하는 hwy (파란색 label)을 구분 지어줄 수 있다.

p + 
  scale_colour_binned()

scale_size_binned

이산형 binning 처리에 항상 애매한 문제가 되는 경계값도 legend에 표기가능!

p + 
  scale_size_binned(guide = guide_bins(show.limits = TRUE))

연속형 데이터를 x축 방향으로 정렬시킴

scale_x_binned()는 x축방향으로 정렬시켜 막대플롯을 연상시키듯 사용할 수가 있다.

p + 
  scale_x_binned()

scale_x_binned과 막대그래프 표현

scale_x_binned과 막대그래프를 동시에 사용한 모습이다.

ggplot(mpg) + 
  geom_bar(aes(displ)) + 
  scale_x_binned()

차트 축 돌리기 (coord_flip()의 대안)

기존에 ggplot2에서 x축과 y축을 바꾸려면 coord_flip()를 사용해야 했으며, 당시에 나에게는 이것조차 새로운 세계였다. 그러나 이제는 이를 좀 더 직관적으로 사용할 수가 있게 되었다.

ggplot(mpg) + 
  geom_bar(aes(x = manufacturer)) + 
  coord_flip()

default로 y만 선택이 가능하다

ggplot의 특성상 default에 x가 들어가야 했던것이 y로 지정해주어 가로에서부터 표현을 할 수 있게 해주었다. (그러나 음… 막상 이기능은 직관적이지 못하다는 인상을 줄 수 있을것 같다. 늘 그렇듯이 dafault는 x라는 생각을 하기 때문인가 보다.)

ggplot(mpg) + 
  geom_bar(aes(y = manufacturer))

geom_smooth 역시 y관점에서 설정이 가능하다

글로벌하게 적용되는 aes 가 아닌 geom_* 함수의 orientation 아규먼트를 통해 개별 geom 단위로 처리하는 것도 가능

ggplot(mpg, aes(displ, hwy)) + 
  geom_point() + 
  geom_smooth(orientation = "y")
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'

좀더 심미적인 그래프

사실, 아까도 말했지만 ggplot의 5%남짓 밖에 사용하지 못하는 나에게도 충분히 이쁜 그래프를 표현할 수 있다고 생각 했었다. 그럼에도 이번에 그래프를 그리는데에 있어, 조금더 이쁜 표현을 설정할 수 있는 기능을 추가 해주었다.

ggplot(mpg, aes(displ)) +
  geom_histogram(aes(y = after_stat(density)))
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

내부를 색으로 채우는 코드

after_scale()코드를 사용하여 내부를 색으로 표현이 가능하다.

ggplot(mpg, aes(class, hwy)) +
  geom_boxplot(aes(colour = class, fill = after_scale(alpha(colour, 0.4))))

하나의 aes 에 여러개의 mapping을 하는 것도 이제 가능함

stage() 기능을 사용.

ggplot(mpg) + 
  geom_bar(
    aes(
      x = drv, 
      colour = stage(start = drv, after_scale = alpha(colour, 0.5))
    ), 
    fill = NA, size = 4
  )
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.

자유롭게 확장 가능한 테마

이 부분은 아직 테마 설정에 대해서 나 역시 자유롭지 못하기에 제대로 이해를 할 수가 없었다.

register_theme_elements(
  ggrelfacet.panel.arrow = element_line(
    size = 3, arrow = arrow()
  ),
  element_tree = list(
    ggrelfacet.panel.arrow = el_def("element_line", "line")
  )
)
## Warning: The `size` argument of `element_line()` is deprecated as of ggplot2 3.4.0.
## ℹ Please use the `linewidth` argument instead.

더 나아진 윤곽 계산

geom_polygon 을 통한 contour 처리는 inner hole 및 next level contour 처리가 안되기에 그래픽이 쪼개진 폴리곤으로 망가져보였다. 이제 geom_contour_* 를 이용하면 깔끔한 처리가 가능해졌다.

Step 1.

윤곽을 계산하는데 있어 보다 선명한 표현을 할 수 있게 되었다. 다음 그림을 보자. 등고선을 표현하려고 하는데 직관적이지도 뚜렷하지도 않다.

volcano_long <- data.frame(
  x = as.vector(col(volcano)),
  y = as.vector(row(volcano)),
  z = as.vector(volcano)
)

ggplot(volcano_long, aes(x, y, z = z)) + 
  geom_polygon(aes(fill = stat(level)), alpha = 0.5, stat = "contour") + 
  guides(fill = "legend")
## Warning: `stat(level)` was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(level)` instead.

Step 2.

geom_contour_filled() 함수를 사용하여 조금 더 선명한 표현을 할 수 있었다.

ggplot(volcano_long, aes(x, y, z = z)) + 
  geom_contour_filled(aes(fill = stat(level)), alpha = 0.5)

Step 3.

이번에 이 모든 문제가 해결되었다. 위 그림과 다른점은 범례를 표현하는데, 연속적인 표현을 이산화 해서 표현을 하였다.

ggplot(volcano_long, aes(x, y, z = z)) + 
  geom_contour_filled(aes(fill = stat(level))) + 
  guides(fill = guide_colorsteps(barheight = unit(10, "cm")))

그외 추가된 기능

  • geom_ribbon, area, density 의 outline stroke 처리 (외곽선 처리)
  • outline.type 아규먼트를 통해 명시적 처리가능
  • upper, lower, both, full 등 4가지 타입 제공
ggplot(mpg) + 
  geom_point(aes(hwy, displ)) + 
  ggtitle("The placement of this title may surprise you") + 
  theme(plot.title.position = "plot")

huron <- data.frame(year = 1875:1972, level = as.vector(LakeHuron))
ggplot(huron, aes(year)) + 
  geom_ribbon(aes(ymin = level - 10, ymax = level + 10), fill = "grey", colour = "black")

 ggplot(diamonds, aes(carat)) +
  geom_density(fill = "grey")


총평

처음으로 새로운 버전에 대해 리뷰를 했다. 아직 많이 미숙해서 제대로 리뷰가 안되었으나 하헌철님의 도움으로 조금 더 전문적인 리뷰를 할 수 있게 되었다. 다음에는 일기처럼 쓰는게 아니라 좀 더 전문적으로 리뷰를 쓰는쪽으로 노력을 해봐야 겠다.