Interactive plot with ggplot2 and ggiraph(3)

오늘은 ggplot2와 ggiraph을 이용한 interaction plot 세번째로 나이팅게일 rose plot과 단계구분도를 interaction plot으로 구현한 예제를 소개하고자 한다.

Rose plot

위 그림은 지난번 Rose plot with ggplot2 라는 글에서 다룬 것과 동일한 그림이다. 하지만 이번 그림은 geom_bar() 대신 geom_bar_interactive()를 이용해 tooltip을 보여주는 것이 다르다. 먼저 그림을 그릴 파일을 읽어들인다.

require(ggiraph)

data=read.csv("rosewide.csv")
data
  group January February March April  May June July August September
1     A      10      5.0     7     9 11.0   13   15   17.0        19
2     B       9      4.5     6     7  8.0    9   10   11.0        12
3     C       8      4.0     5     8  4.0    5    8    4.0         5
4     D       7      3.5     4     7  3.5    4    7    3.5         4
5     E       6      3.0     3     6  3.0    3    6    3.0         3
6     F       5      2.5     2     5  2.5    2    5    2.5         2
7     G       4      2.0     2     4  2.0    2    4    2.0         2
  October November December
1      21     23.0       25
2      13     14.0       15
3       8      4.0        5
4       7      3.5        4
5       6      3.0        3
6       5      2.5        2
7       4      2.0        2

읽어들인 데이타는 전형적인 wide form의 데이타이다. 이 데이타로 그림을 그리기 위해서는 long form으로 변환하여야 한다. 또한 데이타를 그냥 변환하면 알파벳순으로 정렬되어 그림이 그려지므로 1월-12월의 순서에 맞게 범주형 변수로 변환한다.

rose=reshape2::melt(data=data,id="group",variable.name = "Month")
rose$Month=factor(rose$Month,levels=month.name)

마우스 커서를 해당하는 그림 위로 옮겼을 경우 나타낼 내용을 만들어 tooltip이라는 열에 저장한다. 또한 bar의 색깔의 animation을 위해 data_id 열을 만든다.

rose$tooltip=paste0(rose$Month,"<br>",rose$group,"<br>",rose$value)
rose$data_id=as.character(1:nrow(rose))

이를 이용해 p라는 변수에 저장하고 interactive plot을 출력한다.

p<-ggplot(rose,aes(x=Month,fill=group,y=value))+
    geom_bar_interactive(aes(data_id=data_id,tooltip=tooltip),stat="identity",width=1,color="black",size=0.1)+
    scale_fill_brewer(palette="Greens")+coord_polar()

tooltip_css <- "background-color:white;font-style:italic;padding:10px;border-radius:20px 20px 20px 20px;"
ggiraph(code={print(p)},tooltip_extra_css = tooltip_css)

단계구분도(Choropleth map)의 구현

다음은 Shape파일을 이용하여 우리나라 행정구역 지도를 데이타와 병합하여 interactive map으로 그리는 예제이다. 행정구역 지도 Shape파일의 processing 및 단계구분도그리기에 대한 자세한 설명은 저자가 쓴 “웹에서 클릭만으로 하는 R통계분석” 책을 참조하기 바라며 이 글에서는 단계구분도를 그리는 방법에 대해 설명한다.

국가통계포털(kosis.kr)에서 2010년 센서스통계자료를 구하였다. 다음과 같은 자료를 사용한다.

data=read.csv("data/level1.csv")
str(data)
'data.frame':   16 obs. of  27 variables:
 $ code                   : int  39 38 37 36 35 34 33 32 31 26 ...
 $ name                   : Factor w/ 16 levels "강원도","경기도",..: 14 3 4 12 13 15 16 1 2 10 ...
 $ name_eng               : Factor w/ 16 levels "Busan","Chungcheongbuk-do",..: 12 10 9 14 13 3 2 6 8 16 ...
 $ base_year              : int  2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 ...
 $ C행정구역별_읍면동     : int  39 38 37 36 35 34 33 32 31 26 ...
 $ 행정구역별_읍면동      : Factor w/ 16 levels "강원도","경기도",..: 14 3 4 12 13 15 16 1 2 10 ...
 $ 시점                   : int  2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 ...
 $ 총인구_명              : int  531905 3160154 2600032 1741499 1777220 2028002 1512157 1471513 11379459 1082567 ...
 $ 남자_명                : int  263244 1591430 1296071 852513 872724 1023882 758214 738399 5705613 557694 ...
 $ 여자_명                : int  268661 1568724 1303961 888986 904496 1004120 753943 733114 5673846 524873 ...
 $ 내국인_계_명           : int  528411 3119571 2575370 1728749 1766044 2000473 1495984 1463650 11196053 1071673 ...
 $ 내국인_남자_명         : int  261521 1562686 1281510 845952 867630 1007454 748622 735075 5599570 550869 ...
 $ 내국인_여자_명         : int  266890 1556885 1293860 882797 898414 993019 747362 728575 5596483 520804 ...
 $ 외국인_계_명           : int  3494 40583 24662 12750 11176 27529 16173 7863 183406 10894 ...
 $ 외국인_남자_명         : int  1723 28744 14561 6561 5094 16428 9592 3324 106043 6825 ...
 $ 외국인_여자_명         : int  1771 11839 10101 6189 6082 11101 6581 4539 77363 4069 ...
 $ 가구_계_가구           : int  188365 1165209 1014345 684986 663695 758552 564614 560589 3908059 377938 ...
 $ 일반가구_가구          : int  187323 1151172 1005349 681431 659946 749035 558796 557751 3831134 373633 ...
 $ 집단가구_가구          : int  243 2081 1795 843 815 1417 924 658 5307 374 ...
 $ 외국인가구_가구        : int  799 11956 7201 2712 2934 8100 4894 2180 71618 3931 ...
 $ 주택_계_호             : int  159076 1033580 933391 690508 633477 716159 509968 536485 3217483 310952 ...
 $ 단독주택_호            : int  79910 414576 466948 408877 289604 324720 205771 228960 507417 63093 ...
 $ 아파트_호              : int  46239 558688 398002 254331 320469 341296 272554 270845 2183845 218142 ...
 $ 연립주택_호            : int  11137 24737 22978 12630 14163 23403 19048 23434 150705 6730 ...
 $ 다세대주택_호          : int  18802 23456 30984 5625 2838 18123 6315 4684 348542 17716 ...
 $ 비거주용_건물내_주택_호: int  2988 12123 14479 9045 6403 8617 6280 8562 26974 5271 ...
 $ 주택이외의_거처_호     : int  4238 16056 6036 5442 2850 7489 3110 3599 99810 1834 ...

마우스 커서를 해당하는 지역으로 옮겼을 경우 나타낼 내용을 만들어 tooltip이라는 열에 저장한다. 또한 지도 색깔의 animation을 위해 data_id 열을 만든다.

data$tooltip=paste0(data$name,"<br>총인구(명)<br>",data$총인구_명)
data$data_id=1:nrow(data)

Shape파일을 데이타프레임으로 전환한다. 다음의 코드를 사용하여 시도별 단계구분도를 그릴 수 있다.

source("Shape.R")
require(ggplot2)

#시도별 데이터 
kormap1=shape2map("data/level1.shp",transform=TRUE)
Shapefile type: Polygon, (5), # of Shapes: 16
# 시군구별 데이터
kormap2=shape2map("data/level2.shp",transform=TRUE)
Shapefile type: Polygon, (5), # of Shapes: 251
p<-ggplot(data=data,aes(map_id=code,fill=총인구_명,data_id=data_id,tooltip=tooltip))+ 
    expand_limits(x=kormap1$long,y=kormap1$lat)+
    geom_map_interactive(map=kormap1,colour='black',size=0.1)+ 
    coord_map()+ 
    scale_fill_gradientn(colours=c('white','orange','red'))+ 
    ggtitle("전국 시도별 인구 분포도")
ggiraph(code=print(p))