[R] 파이차트 원 안에 글자 넣기

반응형
    반응형

    파이차트 안에 글자를 넣는 방법입니다.
    사실 ggplot2로 하면 다 되긴 하는데 정교하게 만들고 싶다면 수학을 쓸 수 있다는 걸 보여드리고 싶어서 포스팅을 합니다.
    약간 뻘짓이지만 이런 방법도 있다는 것도 구경 한 번 해보셨으면 합니다.
    사실 시각화는 ppt로 만드는게 사실 제일 예쁘고 정밀하게 글자를 넣을 수 있기 때문에 코딩으로는 과도하게 그래프에 집착할 필요가 없습니다.

    ggplot2로 파이차트 안에 글자 넣기

    먼저 간단한 방법은 ggplot2의 기능을 이용하는 것입니다.
    간단하게 원 안에 글자를 넣을 수 있습니다.
    geom_text()를 이용하면 됩니다. 파라미터는 aes와 position 파라미터를 채우는게 기본입니다. aes에는 글자로 만들 값을 넣어주고 poistion에는 글자를 넣을 위치를 작성합니다. 막대차트는 position_dodge로 파이차트는 position_stack으로 입력합니다.

    library(ggplot2)
    v = c(23,15,5)
    k = c('1st','2nd','3rd')
    df = data.frame(rank=k,value=v)
    
    pie = ggplot(df,aes(x="",y=value,fill=rank))+geom_bar(width=10,stat='identity') + coord_polar('y',start=0)+geom_text(aes(label=value),position = position_stack(vjust=0.5))
    pie

    보통 퍼센트를 넣고 싶을텐데 퍼센트를 만들어 놓은 후 aes label 부분에 입력하면 됩니다.

    pct = round(df$value/sum(v)*100,1)
    pie = ggplot(df,aes(x="",y=value,fill=rank))+geom_bar(width=10,stat='identity') + coord_polar('y',start=0)+geom_text(aes(label=paste0(pct,'%')),position = position_stack(vjust=0.5))
    pie

     

     

    함수를 직접 만들어서 글자 넣기

    ggplot2 패키지가 없을 때는 R의 내장함수만으로 원 안에 글자를 넣어야 합니다. R의 pie 함수에는 원 안에 글자 넣는 기능이 없기 때문인데요. 쉬운 작업이 아닙니다.
    ggplot2이 있는게 천만다행인 것 같습니다.

    재미는 없지만 한 번 해보겠습니다.

    파이차트 원 안에 글자를 넣는다고 생각을 해보면 내가 원하는 위치는 경계로 나눠진 각 부채꼴의 중앙에 글자를 넣어야 합니다.
    그러면 저 위치는 어떻게 알 수 있을까요?
    위치 자체를 수치화 한다면 컴퓨터가 알아들을 수 있을겁니다. 좌표평면에 있는 하나의 원이라 여겨 좌표를 구해 수치화를 합니다.

    반지름이 1인 원이라 생각하면 호의길이 공식(l=r$\theta$)에 의해 각도 $\theta$ = $2\pi$ 이 됩니다.
    현재 value 값으로 전체에 대한 퍼센트이므로 각도는 $\theta$ = $2
    \pi*\frac{퍼센트}{100}$ 가 될 것입니다.
    각도를 구한후 x,y 좌표를 얻기 위해서 x=rcos($\theta$),y=rsin($\theta$) 를 계산해 좌표를 구합니다.

    원하는 위치는 각 부채꼴의 중간값에 놓도록 하겠습니다.
    누적 퍼센트를 얻을 수있으니 이를 이용해 구합니다.
    위에서 구한 (x,y) 는 둘레의 위치이므로 같은 비율의 작은 원에 위치하게 하기 위해 radius를 1보다 작게 합니다.

    pieLabel <- function(x,radius = 0.4, init.angle=0){
      p = cumsum(prop.table(x))*2*pi       # 누적 둘레
      p = c(0,p)                           
      q = (diff(p)+2*p[-length(p)])*0.5    # 중간 각도
      a = init.angle                       # 초기 각도
    
      qx = cos(a+q)
      qy = sin(a+q)
    
      coorDf = data.frame(x=radius*qx,y=radius*qy)
      return(coorDf)
    }
    
    pie(x=v,label=k)
    text(pieLabel(v,radius=0.5),labels=sprintf('%3.1f%%',100*prop.table((v))))

     

    마치며

    함수를 만드는 작업은 파이썬에서도 같은 방법으로 할 수 있습니다.

    물론 세부 코드는 당연히 다르겠지만요.

    아무튼 원 안에 글자 넣는 방법에 대해 알아보았는데요.

    역시 좋은 패키지가 있는게 빠르게 작업을 할 수 있어서 좋은 것 같습니다.

     

    관련 포스팅
    [R] 파이차트(pie plot) 기본, 색상 바꾸기
    [R] tidyverse 간단소개 및 설치

    댓글

    Designed by JB FACTORY

    ....