(ggplot2) 지도위에 특정 위치 표시하기

특정 위치를 표시하기 위해서는 숫자로 경도/위도를 표시만 해서는 안되고, sf 객체로 바꿔야 한다. Simple features(sf)는 점(points), 선(lines), 다각형(polygons) 등 공간 데이터를 다루기 위한 패키지이다. 특히 sf 패키지는 ggplot2와 연동하여 공간 데이터의 시각적 표현이 용이하다.

SF 클래스로 변환하기

숫자로만 이루어진 특정 위치(x, y)를 sf 클래스로 만들려면 총 3번의 변환이 필요하다. 경도/위도를 나타내는 한 쌍의 숫자를 sfg 클래스로 변환환다.

# Simple feature geometries (sfg) 클래스.
st_point(c(128, 37))
# 출력결과.
POINT (128 37)

그 다음에 sfc 클래스로 변환한다.

# Simple feature columns (sfc) 클래스.
st_point(c(128, 37)) |> 
  st_sfc(crs = "EPSG:4326")

# 출력결과.
Geometry set for 1 feature 
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 128 ymin: 37 xmax: 128 ymax: 37
Geodetic CRS:  WGS 84
POINT (128 37)

마지막에 sf 클래스로 변환하면 된다. 여기 _ 는 R 기본 파이프 |>를 사용할 때 맨 앞의 인자로 값을 전달하지 않는 경우, 원하는 전달 위치를 지정하기 위해 사용한다.

# Simple feature (sf) 클래스.
st_point(c(128, 37)) |> 
  st_sfc(crs = "EPSG:4326") |> 
  st_sf(geometry = _) 

# 출력결과.
Simple feature collection with 1 feature and 0 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 128 ymin: 37 xmax: 128 ymax: 37
Geodetic CRS:  WGS 84
        geometry
1 POINT (128 37)

만약에 여러개면, dplyr 함수를 이용해서 아래 처럼 만들수도 있다.

tibble(lon = c(128, 125), lat = c(37, 35)) |> 
  mutate(x = map2(lon, lat, c)) |> 
  mutate(geom = map(x, st_point)) |> 
  pull(geom) |> 
  st_sfc(crs = "EPSG:4326")  |> 
  st_sf(geometry = _) 

# 출력결과.
Simple feature collection with 2 features and 0 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 125 ymin: 35 xmax: 128 ymax: 37
Geodetic CRS:  WGS 84
        geometry
1 POINT (128 37)
2 POINT (125 35)

그런데, 더 쉬운 방법이 있었다. st_as_sf 함수를 사용하면 편하다.

data.frame(lon = c(128, 125), lat = c(37, 35)) |> 
  st_as_sf(coords = c("lon", "lat"), crs = "EPSG:4326")

# 출력결과.
Simple feature collection with 2 features and 0 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 125 ymin: 35 xmax: 128 ymax: 37
Geodetic CRS:  WGS 84
        geometry
1 POINT (128 37)
2 POINT (125 35)

지도위에 표시하기

지도위에 표시할 포인트 2개를 준비해놓는다.

points = data.frame(lon = c(127, 129), lat = c(37.5, 36)) |> 
  st_as_sf(coords = c("lon", "lat"), crs = "EPSG:4326")

이제 간단하다 geom_sf 함수를 하나더 붙여서 지도위에 포인트를 그리면 된다.

ggplot() +
  geom_sf(data = sig_map) + # 전체지도
  geom_sf(data = points)    # 포인트2개

일반 geom_point 에서 사용하던 shape, size, colour 도 동일하게 사용가능하다.

ggplot() +
  geom_sf(data = sig_map) +
  geom_sf(data = points, size = 3, shape = 1, colour = "blue")

geom_point 로 아예 바꾸고 싶다면 아래처럼 stat 를 지정해서 사용하면 된다.

ggplot() +
  geom_sf(data = sig_map) +
  geom_point(data = points, aes(geometry = geometry),
             shape = 1, size = 3, colour = "blue",
             stat = "sf_coordinates")

더 보면 좋을 글들