결론부터 말하자면 legend의 모양을 바꾸기 위해서는 html 코드를 작성하여 R 함수에 넣어야한다. html 코드는 도형 모양 부터 라벨까지 일일이 다 만들어야하고 위치도 각각 설정해야한다.
html 코드를 만드는 함수는 아래와 같다.
# addLegendCustom
addLegendCustom<-function(map,colors,labels,sizes,shapes,borders,ms,ml,mt,opacity = 0.4){
make_shapes<-function(colors,sizes,borders,shapes,ms) {
shapes<-gsub("circle", "50%", shapes)
shapes<-gsub("square", "0%", shapes)
paste0(colors,"; width:",sizes,"px; height:",sizes,"px; border:1px solid ",borders,"; border-radius:",shapes,";margin-left:",ms,"px",";margin-top: 7px;")
}
make_labels<-function(sizes,labels,ml,mt) {
paste0("<div style='display: inline-block;height: ",sizes,"px;margin-top:",mt,"px;line-height: ",sizes, "px;margin-left:",ml,"px;'>",labels,"</div>")
}
legend_colors<-make_shapes(colors, sizes, borders, shapes,ms)
legend_labels<-make_labels(sizes, labels,ml,mt)
return(addLegend(map, colors = legend_colors, labels = legend_labels, opacity = opacity,position="bottomleft",title="Abundance"))
}
addLegendCustom 함수는 addLegendCustom(legend를 입력할 지도,도형의 색,도형의 label,도형의 크기,도형의 모양,도형 테두리 색,도형의 왼쪽 마진,label의 왼쪽 마진,label의 위쪽 마진)으로 구성되어있다.
(1) make_shapes
addLegendCustom 함수 안에 있는 make_shapes 함수는 도형을 만들고 위치를 설정하는 함수이다. make_shapes(도형의 색,도형의 크기,도형의 테두리 색,도형의 모양,도형의 왼쪽 마진)으로 구성되어있다.
안의 코드를 살펴보면 gsub 함수를 이용하여 shapes가 circle인 경우 50%, 사각형인 경우 0%으로 바꿔준다. html에서는 'border-radius: 50%' 입력시 원을 표현해준다. 'border-radius: 0%'는 사각형이다. paste0을 살펴보면 'border-radius:' 다음에 shapes 백터를 붙여 html 코드를 만든다.
paste0는 백터 순서대로 값을 붙여주는 함수이다. 예를 들면 아래와 같다.
> paste0(1:12, c("st", "nd", "rd", rep("th", 9)))
[1] "1st" "2nd" "3rd" "4th" "5th" "6th" "7th" "8th" "9th" "10th" "11th" "12th"
1:12에서 첫 번째 값 1, c("st", "nd", "rd", rep("th", 9))에서 첫 번째 값 'st'를 붙여서 1st를 만든다. 1:12에서 두 번째 값 2, c("st", "nd", "rd", rep("th", 9))에서 두 번째 값 'nd'를 붙여서 2nd를 만든다... 12까지 만들어준다.paste0 안에 있는 코드를 세분화해서 설명하면 아래와 같다.
여기서 주의 할 점은 width와 height의 크기가 같지 않으면 타원이 표현된다. 위 html 코드를 변형시키면서 원하는 도형의 모양과 위치를 설정하면 된다.
(2) make_labels
make_labels 함수는 label을 만들고 위치를 설정하는 함수이다. paste0 안에 있는 코드를 세분화해서 설명하면 아래와 같다.
마찬가지로 위 html 코드를 변형시키면서 원하는 도형의 모양과 위치를 설정하면 된다.
(3) 마무리
각 변수의 값을 설정했을 때 make_shapes와 make_labels로 생성한 html 코드는 아래와 같음을 확인할 수 있다.
1) make_shapes으로 생성한 html 코드
# addLegendCustom variable
colors <- c("red","blue","blue","blue","white")
labels <- c("1000","100","10","1","1>")
sizes <- (c(log(1000+1),log(100+1),log(10+1),log(1+1),log(0.5+1))+1)*4
shapes <- c("circle","circle","circle","circle","circle")
borders <- c("red","blue","blue","blue","black")
ms<-c(0,5,9,12.5,13)
mt<-c(7,7,8,0,0)
ml<-c(0,9,18,25,23)
> legend_colors
[1] "red; width:31.6350191172609px; height:31.6350191172609px; border:1px solid red; border-radius:50%;margin-left:0px;margin-top: 7px;"
[2] "blue; width:22.460482067365px; height:22.460482067365px; border:1px solid blue; border-radius:50%;margin-left:5px;margin-top: 7px;"
[3] "blue; width:13.5915810911935px; height:13.5915810911935px; border:1px solid blue; border-radius:50%;margin-left:9px;margin-top: 7px;"
[4] "blue; width:6.77258872223978px; height:6.77258872223978px; border:1px solid blue; border-radius:50%;margin-left:12.5px;margin-top: 7px;"
[5] "white; width:5.62186043243266px; height:5.62186043243266px; border:1px solid black; border-radius:50%;margin-left:13px;margin-top: 7px;"
2) make_labels로 생성한 html 코드> legend_labels
[1] "<div style='display: inline-block;height: 31.6350191172609px;margin-top:7px;line-height: 31.6350191172609px;margin-left:0px;'>1000</div>"
[2] "<div style='display: inline-block;height: 22.460482067365px;margin-top:7px;line-height: 22.460482067365px;margin-left:9px;'>100</div>"
[3] "<div style='display: inline-block;height: 13.5915810911935px;margin-top:8px;line-height: 13.5915810911935px;margin-left:18px;'>10</div>"
[4] "<div style='display: inline-block;height: 6.77258872223978px;margin-top:0px;line-height: 6.77258872223978px;margin-left:25px;'>1</div>"
[5] "<div style='display: inline-block;height: 5.62186043243266px;margin-top:0px;line-height: 5.62186043243266px;margin-left:23px;'>1></div>"
마지막으로 addLegend의 colors에 legend_colors, lables에 legend_labels를 입력하고 설정사항을 추가하면 완성이다.return(addLegend(map, colors = legend_colors, labels = legend_labels, opacity = opacity,position="bottomleft",title="Abundance"))
생성한 함수를 이용하여 맵에 legend를 그리려면 addLegend가 있던 곳에 addLegendCustom 함수를 입력하면 된다.m <- leaflet(data=data) %>%
setView(lng=128, lat=37 , zoom=6) %>%
addProviderTiles(providers$CartoDB.Positron) %>%
addLegendCustom(colors,labels,sizes,shapes,borders,ms,ml,mt)
최종 코드는 아래와 같다.
1. ui.R
library(shiny)
library(leaflet)
ui <- fluidPage(
leafletOutput("map",height = 800)
)
2. server.Rlibrary(shiny) library(leaflet) server <- function(input,output, session){ output$map <- renderLeaflet({ # addLegendCustom addLegendCustom<-function(map,colors,labels,sizes,shapes,borders,ms,ml,mt,opacity = 0.4){ make_shapes<-function(colors,sizes,borders,shapes,ms) { shapes<-gsub("circle", "50%", shapes) shapes<-gsub("square", "0%", shapes) paste0(colors,"; width:",sizes,"px; height:",sizes,"px; border:1px solid ",borders,"; border-radius:",shapes,";margin-left:",ms,"px",";margin-top: 7px;") } make_labels<-function(sizes,labels,ml,mt) { paste0("<div style='display: inline-block;height: ",sizes,"px;margin-top:",mt,"px;line-height: ",sizes, "px;margin-left:",ml,"px;'>",labels,"</div>") } legend_colors<-make_shapes(colors, sizes, borders, shapes,ms) legend_labels<-make_labels(sizes, labels,ml,mt) return(addLegend(map, colors = legend_colors, labels = legend_labels, opacity = opacity,position="bottomleft",title="Abundance")) } ###################################################################### # addLegendCustom variable colors <- c("red","blue","blue","blue","white") labels <- c("1000","100","10","1","1>") sizes <- (c(log(1000+1),log(100+1),log(10+1),log(1+1),log(0.5+1))+1)*4 shapes <- c("circle","circle","circle","circle","circle") borders <- c("red","blue","blue","blue","black") ms<-c(0,5,9,12.5,13) mt<-c(7,7,8,0,0) ml<-c(0,9,18,25,23) ###################################################################### m <- leaflet(data=data) %>% setView(lng=128, lat=37 , zoom=6) %>% addProviderTiles(providers$CartoDB.Positron) %>% addLegendCustom(colors,labels,sizes,shapes,borders,ms,ml,mt) }) }
결과를 확인해보면 짜임새 있게 구성된 legend를 확인할 수 있다.
※ 참고문헌
https://stackoverflow.com/questions/52812238/custom-legend-with-r-leaflet-circles-and-squares-in-same-plot-legends
https://developer.mozilla.org/en-US/docs/Web/CSS/line-height
https://www.w3schools.com/css/tryit.asp?filename=trycss_inline-block_span1
0 개의 댓글:
댓글 쓰기