테마
Folium 지리 시각화
학습 목표
- Folium 라이브러리로 인터랙티브 지도를 생성할 수 있다
- Marker, CircleMarker로 위치 데이터를 지도에 표시할 수 있다
- MarkerCluster로 대량의 마커를 효율적으로 관리할 수 있다
- Choropleth 지도로 지역별 통계 데이터를 색상으로 표현할 수 있다
- 위도/경도 데이터를 활용한 지리 시각화 워크플로우를 이해한다
전체 구조
1. Folium 소개와 설치
Folium은 Python에서 Leaflet.js 기반의 인터랙티브 지도를 만드는 라이브러리다. 주피터 노트북에서 바로 지도를 확인할 수 있다.
python
# 설치 (아직 설치되지 않은 경우)
# pip install folium
# conda install -c conda-forge folium
import folium2. 기본 지도 생성 - folium.Map
python
# 서울 시청 좌표 기준 지도
m = folium.Map(
location=[37.5665, 126.9780], # [위도, 경도]
zoom_start=12 # 초기 줌 레벨
)
m지도 타일(Tile) 변경
python
# OpenStreetMap (기본값)
m = folium.Map(location=[37.5665, 126.9780], tiles="OpenStreetMap")
# CartoDB Positron (밝은 톤)
m = folium.Map(location=[37.5665, 126.9780], tiles="CartoDB positron")
# CartoDB dark_matter (어두운 톤)
m = folium.Map(location=[37.5665, 126.9780], tiles="CartoDB dark_matter")3. Marker - 위치 표시
python
m = folium.Map(location=[37.5665, 126.9780], zoom_start=13)
# 마커 추가
folium.Marker(
location=[37.5665, 126.9780],
popup="서울 시청", # 클릭 시 표시
tooltip="여기를 클릭하세요", # 마우스 호버 시 표시
icon=folium.Icon(color="red", icon="info-sign")
).add_to(m)
m여러 마커 한 번에 추가
python
# 상권 데이터에서 상위 100개 마커 표시
m = folium.Map(location=[37.5, 127.0], zoom_start=11)
for idx, row in df.head(100).iterrows():
folium.Marker(
location=[row["위도"], row["경도"]],
popup=row["상호명"],
tooltip=row["상권업종대분류명"]
).add_to(m)
m4. CircleMarker - 원형 마커
CircleMarker는 크기와 색상을 조절할 수 있어 데이터 값을 시각적으로 표현하기 좋다.
python
m = folium.Map(location=[37.5, 127.0], zoom_start=11)
for idx, row in df.sample(200).iterrows():
folium.CircleMarker(
location=[row["위도"], row["경도"]],
radius=3, # 원의 반지름
color="blue", # 테두리 색
fill=True, # 채우기 여부
fill_color="blue", # 채우기 색
fill_opacity=0.5, # 채우기 투명도
popup=row["상호명"]
).add_to(m)
m5. MarkerCluster - 마커 군집화
대량의 마커가 있을 때 줌 레벨에 따라 자동으로 군집화/해제하는 기능이다.
python
from folium.plugins import MarkerCluster
m = folium.Map(location=[37.5, 127.0], zoom_start=11)
# MarkerCluster 객체 생성
marker_cluster = MarkerCluster().add_to(m)
# 클러스터에 마커 추가
for idx, row in df.sample(1000).iterrows():
folium.Marker(
location=[row["위도"], row["경도"]],
popup=row["상호명"]
).add_to(marker_cluster) # m이 아니라 marker_cluster에 추가
mMarkerCluster 핵심: 마커를
m(Map)이 아닌marker_cluster객체에 추가해야 군집화가 동작한다.
6. Choropleth - 단계 구분도
Choropleth 지도는 지역별 통계 데이터를 색상 농도로 표현한다. GeoJSON 파일과 데이터를 연결하여 만든다.
python
import json
# GeoJSON 파일 로드 (시도 경계)
geo_data = json.load(open("data/korea_sido.geojson", encoding="utf-8"))
# 시도별 매장 수 집계
sido_count = df["시도명"].value_counts()
# Choropleth 지도 생성
m = folium.Map(location=[36.5, 127.5], zoom_start=7)
folium.Choropleth(
geo_data=geo_data, # GeoJSON 데이터
data=sido_count, # 표시할 데이터
columns=[sido_count.index, sido_count.values],
key_on="feature.properties.name", # GeoJSON 속성과 매칭
fill_color="YlOrRd", # 색상 팔레트
fill_opacity=0.7,
line_opacity=0.3,
legend_name="매장 수"
).add_to(m)
mChoropleth 작동 원리
Choropleth 색상 팔레트 옵션
| 팔레트 | 설명 |
|---|---|
YlOrRd | 노랑 → 주황 → 빨강 |
YlGn | 노랑 → 초록 |
BuPu | 파랑 → 보라 |
RdYlGn | 빨강 → 노랑 → 초록 |
Blues | 연한 파랑 → 진한 파랑 |
7. 지도 저장
python
# HTML 파일로 저장
m.save("map_output.html")
# 브라우저에서 열기
import webbrowser
webbrowser.open("map_output.html")8. 실전 예시: 상권 분석 지도
python
# 음식점만 필터링
df_food = df[df["상권업종대분류명"] == "음식"].copy()
# 서울 강남구만 필터링
df_gangnam = df_food[df_food["시군구명"] == "강남구"].copy()
# 지도 생성
m = folium.Map(location=[37.497, 127.028], zoom_start=14,
tiles="CartoDB positron")
# MarkerCluster로 마커 추가
cluster = MarkerCluster().add_to(m)
for idx, row in df_gangnam.iterrows():
folium.CircleMarker(
location=[row["위도"], row["경도"]],
radius=2,
color="red",
fill=True,
fill_opacity=0.6,
popup=f"{row['상호명']} ({row['상권업종소분류명']})"
).add_to(cluster)
m핵심 정리
- folium.Map으로 위도/경도 기반 인터랙티브 지도를 생성한다
- Marker: 아이콘 마커, CircleMarker: 원형 마커 (크기/색상 커스터마이징)
- MarkerCluster: 대량 마커의 줌 레벨별 자동 군집화
- Choropleth: GeoJSON + 데이터로 지역별 통계를 색상으로 표현
- 마커에 popup(클릭)과 tooltip(호버)으로 정보를 표시한다
- 완성된 지도는
.save("파일명.html")로 HTML 파일로 저장한다