티스토리 뷰

반응형

아래와 같은 막대그래프를 하나 그려보면서 공부한걸 정리해본다. 간단해 보이지만, 막대그래프를 y 축을 기준으로 표현했고, 하나의 값으로 그린게 아니라 여러값을 그룹핑하여 쌓아(stacked) 표현했고, 마지막으로 수치들을 막대그래프 위에 혹은 우측에 텍스트로 표현하는 것까지 구현해야 한다.

 

그래프를 그리고자하는 스킬보다는 데이터를 이해하는게 더 중요하다. 아래와 같은 그룹형으로 스택(stacked)형의 막대를 쌓기 위해서는 기본적으로 수치간에 그룹핑을 할 수 있는 값들이 추가로 필요하다. 여기서 date 는 양배추 심은 일자, cultivar 는 양배추 품종, weight 양배추 수확 무게 인듯 하다. 어쨋든 일자별로 심은 품종별로 무게를 bar 차트로 구현하는게 목적이며, 그 그룹핑을 할 수 있는 컬럼은 다 준비되어 있다. gcookbook 없으신 분들은 install 하시면 된다.

library(gcookbook)
cabbage_exp

# 출력결과
  Cultivar Date Weight        sd  n         se
1      c39  d16   3.18 0.9566144 10 0.30250803
2      c39  d20   2.80 0.2788867 10 0.08819171
3      c39  d21   2.74 0.9834181 10 0.31098410
4      c52  d16   2.26 0.4452215 10 0.14079141
5      c52  d20   3.11 0.7908505 10 0.25008887
6      c52  d21   1.47 0.2110819 10 0.06674995

 

있는 데이터를 그대로 사용해서, 간단하게 누적 막대그래프를 그려보자. x, y 축 정의하고, fill 을 정의하면 색깔을 구분별로 나눌 수 있다.

ggplot(cabbage_exp, aes(x = Weight, y = Date,fill = Cultivar)) +
  geom_col(width = 0.5)

 

geom_text 로 레이블 표시

근데 내가 원하는 그림은 아래와 같이 수치를 넣어야 했다. (1)번으로 표시한 영역은 각 구분별로 막대차트 상단에 각각 수치 표시하고, (2)번은 막대 맨 우측에는 합산된 수치를 넣어주는 것까지 해보기로 했다.

그러기 위해서는 데이터에 레이블 위치 정보를 추가해야 한다. 1번레이블을 표현하기 위해서는 label_1 컬럼을 정의해놓아야 한다. cumsum 함수를 이용해서 수치가 표시될 x 축 위치를 정의해야 하고, 마지막으로 2번레이블은 합산된 값이니 중복되더라도 label_2 로 x축위치를 정의한다. 요약하자면, label_1 과 label_2 는 텍스트의 x 축 위치를 정의한것 뿐이다.

ce = cabbage_exp %>%
  arrange(Date, desc(Cultivar)) %>% 
  group_by(Date) %>% 
  mutate(label_1 = cumsum(Weight) - 0.5 * Weight) %>% 
  mutate(label_2 = sum(Weight))
  
# A tibble: 6 × 8
# Groups:   Date [3]
  Cultivar Date  Weight    sd     n     se label_1 label_2
  <fct>    <fct>  <dbl> <dbl> <int>  <dbl>   <dbl>   <dbl>
1 c52      d16     2.26 0.445    10 0.141    1.13     5.44
2 c39      d16     3.18 0.957    10 0.303    3.85     5.44
3 c52      d20     3.11 0.791    10 0.250    1.56     5.91
4 c39      d20     2.8  0.279    10 0.0882   4.51     5.91
5 c52      d21     1.47 0.211    10 0.0667   0.735    4.21
6 c39      d21     2.74 0.983    10 0.311    2.84     4.21
반응형

이제 레이블을 넣어본다. vjust / hjust 를 이용해서 약간씩 이동을 해주면 완성이다. xlim 을 사용한 이유는 저게 없으면 맨 우측의 합산된 수치의 레이블이 잘리다보니, xlim 을 이용해서 x 축값을 더 넓게 표현했다. 

ggplot(ce, aes(x = Weight, y = Date,fill = Cultivar)) +
  geom_col(width = 0.5) +
  geom_text(aes(x = label_1, label = Weight), vjust = -3) +
  geom_text(aes(x = label_2, label = label_2), hjust = -0.2) + 
  xlim(0, max(ce$label_2) * 1.1)

 

이번에는 레이블을 막대그래프 가운데에 하얀색으로 표시해본다. 아래 2개 소스는 동일한 결과를 가져온다. label_1 을 정의해서 text 위치를 직접정의 해도 되지만, position_stack 으로 하면 더 소스는 간단해진다.

ggplot(ce, aes(x = Weight, y = Date,fill = Cultivar)) +
  geom_col(width = 0.5) +
  geom_text(aes(x = label_1, label = Weight), colour = "white") +
  geom_text(aes(x = label_2, label = label_2), hjust = -0.2) + 
  xlim(0, max(ce$label_2) * 1.1)
  
ggplot(ce, aes(x = Weight, y = Date,fill = Cultivar)) +
  geom_col(width = 0.5) +
  geom_text(aes(label = Weight), position = position_stack(vjust = 0.5), colour = "white") +
  geom_text(aes(x = label_2, label = label_2), hjust = -0.2) + 
  xlim(0, max(ce$label_2) * 1.1)

 

약간 테마를 바꿔서, 세로로 막대를 바꾸는 것까지 해본다. 끝.

ggplot(ce, aes(x = Date, y = Weight,fill = Cultivar)) +
  geom_col(width = 0.5) +
  geom_text(aes(label = Weight), position = position_stack(vjust = 0.5)) +
  geom_text(aes(y = label_2, label = label_2), vjust = -0.7) + 
  ylim(0, max(ce$label_2) * 1.1) + 
  theme_minimal() +
  scale_fill_brewer(palette = "Blues")

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함