Lovetoken

저는 개발 취향을 가진 데이터 분석가 Jr. 입니다.

Navigation
 » Home
 » About Me
 » Github

R에서 ggmap, ggplot2 패키지를 이용한 지도 출력 및 경로 표현하기 간단예제

18 Oct 2016 » R, Data_Visualization



“map” 이란 단어에 “Google” 의 “g” 알파벳 2개를 덧붙인 것으로 추정이 바로 되는
ggmap packageGoogle map API 를 이용하여 지도자료를 불러와주는 역할을 하는 패키지이다.

간략한 예제를 통해 “ggmap” 패키지의 주요 함수 get_googlemap(), ggmap() 2개의 사용방법을 알아본 후
지도위에 간단한 경로를 결합하는 간단한 예제를 실습해 보고자 한다.



우리나라 지도 호출

getmap <- get_googlemap("seoul")
ggmap(getmap)

위의 2줄 코드는 서울시를 중심으로 google 지도 그림을 로드시켜
R에 plotting 하는 코드이다.

정말 간단한 로직으로 동작하는 편이다.

  1. get_googlemap() 함수를 통해 불러오고 싶은 곳의 장소를 문자열 값으로 첫 번째 인자에 넣어 실행해 이를 객체화 함
  2. ggmap() 함수 안에 방금 만든 객체를 입력시킨 후 실행하면 원하는 장소를 중심으로 구글 지도가 plotting 됨

로직이 이처럼 간단하므로 앞으로 체인연산자(chain operation)를 사용해 간단히 한 줄로 실행하겠다.

get_googlemap("seoul") %>% ggmap



ggplot2 의 함수들과 조합

ggmap() 으로 반환되는 결과물은 기본적으로 ggplot 기반의 결과물인데 이점을 이용하여 ggplot2 패키지의 함수와 조합해 지도 위에 새로운 정보들을 더할 수 있다.
“ggmap”, “ggplot2” 이 두 패키지의 조합은 다양한 Geo Visualization(지리적 시각화) 을 구사할 수 있는 잠재력이 있을거라 생각된다.
지금은 복잡한 실습보단 간단한 예제를 통해 맛보기를 아래처럼 해보았다.

그림을 다시 자세히 보면 x축이 “lon” 이라고 적혀있고, y축은 “lat” 라고 적혀 있다.
“lon” 은 경도(longitude), “lat” 은 위도(latitude) 를 각각 뜻한다고 볼 수 있다.

즉 위도와 경도의 데이터가 있다면 이 지도 위에 ggplot2 를 이용하여 무언가를 덧그릴 수 있을 것이다.


포인팅

의미는 크게 없지만, 서초역과 강남역 부근에 무언가 장난을 쳐보려 한다.

  • 서초역 : 경도 127.007675, 위도 37.491843
  • 강남역 : 경도 127.027544, 위도 37.497968


(127.007675, 37.491843), (127.027544, 37.497968)
좌표에 점을 찍게 되면 서초역과 강남역의 위치에 다음과 같은 모습이 된다.

p1 <- get_googlemap("seoul") %>% ggmap

locationInfo <- data.frame(
  Name = c("서초역", "강남역"), 
  lon = c(127.007675, 127.027544),
    lat = c(37.491843, 37.497968)
)

p1 + geom_point(data = locationInfo, aes(x = lon, y = lat))

잘 안 보일 수도 있지만 전 사진과 다르게 2개의 점이 추가된 것을 볼 수 있다.
2개의 검은 점은 각각 서초역과 강남역에 찍혔다.

지도를 조금 더 확대해 볼 수도 있다.

p2 <- get_googlemap("gangnamgu", zoom = 12) %>% ggmap
p2

지도의 중앙을 “gangnamgu” 즉 강남구로 설정하고 zoom 인자를 12값으로 설정한 경우이다.
zoom 인자의 디폴트 값 10 보다 큰 값을 주었으므로 조금은 확대되어 보이게 된다.

p2 + geom_point(data = locationInfo, aes(x = lon, y = lat))

지도를 확대하든 지도의 중심점을 옮기든 간에 서초역과 강남역에 포인팅하는 코드는 문제없이 작동한다.
포인팅 말고도 포인팅된 곳에 무엇이 위치해 있는지 라벨링이 되어있다면 더 보기 좋을 것이다.
라벨링도 ggplot2 기능 그대로 쓰던대로 쓰면 된다.
아래는 geom_text() 를 이용해본 예이다.

p2 + geom_point(data = locationInfo, aes(x = lon, y = lat)) +
  geom_text(data = locationInfo, aes(label = Name), size = 3, vjust = -1)


경로 그리기

locationInfo <- data.frame(
    Name = c("강남", "양재", "양재시민의숲", "청계산입구", "판교", "정자"), 
    lon = c(127.028046, 127.035140, 127.038451, 127.054769, 127.111172, 127.108367), 
    lat = c(37.497001, 37.483368, 37.469655, 37.448196, 37.394786, 37.366777)
)

locationInfo
##           Name      lon      lat
## 1         강남 127.0280 37.49700
## 2         양재 127.0351 37.48337
## 3 양재시민의숲 127.0385 37.46966
## 4   청계산입구 127.0548 37.44820
## 5         판교 127.1112 37.39479
## 6         정자 127.1084 37.36678

신분당선을 기준으로 정자역에서 강남역까지 경로를 표현해 보고자 locationInfo 내용을 바꾸었다.
이를 이용하여 신분당선의 대략적인 경로를 표현해 보도록 하겠다. 1

p3 <- get_googlemap("gwacheon", zoom = 11) %>% ggmap
p3 <- p3 + geom_point(data = locationInfo, aes(x = lon, y = lat)) +
  geom_text(data = locationInfo, aes(label = Name), size = 4, hjust = 1.2, fontface = "bold")
p3

우선 과천시를 중심으로 두고 zoom = 11 로 설정하여 지도를 뿌린 후
신분당선에 해당되는 역에 점을 찍고 라벨링을 더해보았다.

p3 + geom_path(data = locationInfo, aes(x = lon, y = lat), color = "blue", alpha = .5, lwd = 1)

그다음 경로를 표현하기 위해 각 점에 적당한 직선을 geom_path() 를 통해 그리면 신분당선의 경로가 어떤지를 볼 수 있겠다.



기타

소개한 get_googlemap(), ggmap() 함수의 옵션들은 정말 방대한 편이다.
모든 것을 건드려 보진 못했지만 유용할 것으로 생각하는 기능 중

  1. 지도를 꽉 채워 출력하는 기능
  2. Map type 을 변경하는 기능

이 눈에 띄었다.


extent = "device" 로 지도 꽉 채워 보기

get_googlemap() %>% ggmap

ggmap() 함수를 디폴트로 사용한 결과이다.
지도 그림만을 출력하지 못하고 x축, y축이 함께 그려지는데 상황에 따라 불필요할 수 있다.
온전히 지도 그림만을 출력하고 싶다면

get_googlemap() %>% ggmap(extent = "device")

extent = "device" 를 이용하면 되겠다.


get_googlemap() 함수의 maptype 인자를 조정해 지도스타일 바꾸기

get_googlemap() 함수의 maptype 인자 값을
“terrain”, “satellite”, “roadmap”, “hybrid” 등으로 조절해보면

satellite 로 설정한 결과

p4 <- get_googlemap(maptype = "satellite") %>% ggmap
p4 + ggtitle("maptype : satellite")

terrain 로 설정한 결과

p5 <- get_googlemap(maptype = "terrain") %>% ggmap
p5 + ggtitle("maptype : terrain")

roadmap 로 설정한 결과

p6 <- get_googlemap(maptype = "roadmap") %>% ggmap
p6 + ggtitle("maptype : roadmap")

hybrid 로 설정한 결과

p7 <- get_googlemap(maptype = "hybrid") %>% ggmap
p7 + ggtitle("maptype : hybrid")

이처럼 쓰임에 맞는 지도 스타일을 선택할 수 있다.



Reference


  1. 참고로 지금의 신분당선은 이보다 노선이 더 많아졌다.↩︎