오늘은 ggplot2와 ggiraph을 이용한 interaction plot 세번째로 나이팅게일 rose plot과 단계구분도를 interaction 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)
다음은 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))
시군구별 인구통계지도도 다음과 같은 코드로 그릴 수 있다.
data=read.csv("data/level2.csv")
data$tooltip=paste0(data$name,"<br>총인구(명)<br>",data$총인구_명)
data$data_id=1:nrow(data)
p<-ggplot(data=data,aes(map_id=code,fill=총인구_명,data_id=data_id,tooltip=tooltip))+
expand_limits(x=kormap2$long,y=kormap2$lat)+
geom_map_interactive(map=kormap2,colour='black',size=0.1)+
coord_map()+
scale_fill_gradientn(colours=c('white','orange','red'))+
ggtitle("전국 시군구별 인구 분포도")
ggiraph(code=print(p),tooltip_extra_css = tooltip_css)
읍면동별 인구통계지도 중 부산시만 그리고 싶은 경우 다음과 같은 코드로 그릴 수 있다.
data3=read.csv("data/level3.csv")
kpmap3=mergeShapeData("data/level3.shp",data3,transform=TRUE)
Shapefile type: Polygon, (5), # of Shapes: 3472
Pusan=kpmap3[grep("^21",kpmap3$code),]
Pusan$tooltip=paste0(Pusan$name,"<br>총인구(명)<br>",Pusan$총인구_명)
Pusan$data_id=1:nrow(Pusan)
p<-ggplot(data=Pusan,aes(x=long,y=lat,group=group,fill=총인구_명,data_id=data_id,tooltip=tooltip))+
geom_polygon_interactive(colour='black',size=0.1)+
coord_map()+
scale_fill_gradientn(colours=c('white','orange','red'))+
ggtitle("부산시 동별 인구 분포도")
ggiraph(code=print(p),tooltip_extra_css = tooltip_css)
세번에 걸쳐 소개한 interaction plot은 곧 web-r.org에서 서비스하고 있는 “learn ggplot2”" 앱을 통하여 클릭만으로 그릴 수 있도록 할 예정이며 소스파일도 모두 공개할 예정이다.