folium 지도 시각화¶
In [3]:
# Windows, mac(intel, m1)
# !pip install folium : 콘다로 설치하면 정상 설치가 안됨
# Windows : 이를 설치해야 폴리움 실행시 오류가 안뜸
# !pip install charset
# !pip install charset-normalizer
In [4]:
import folium #폴리움: 위도와 경도를 알려주면 지도를 보여주는 라이브러리
import pandas as pd
import json #json파일도 다룰 것이 때문에 임포트해줌
folium.Map()¶
- 가장 기본적인 지도를 그리는 메서드
folium.Maps(shift tab을 통한 docstring 확인
Parameters
----------
location: tuple or list, default None
Latitude and Longitude of Map (Northing, Easting).
In [5]:
# 구글지도에서 원하는 지역 우클릭 후 출발지로 선정하면 주소창에 위도와 경도 표시됨, 이를 복사
m = folium.Map(location=[37.544564958079896, 127.05582307754338], zoom_start=14) #성수역
#zoom_start=14 성수역 부근이 자세히 나옴, 줌범위 0 ~ 18
#줌범위 0이면 세계지도형태, 18과 19차이없음, 10이 디폴트값(독스트링 확인)
m
Out[5]:
Make this Notebook Trusted to load map: File -> Trust Notebook
save("path")¶
In [6]:
m.save("./folium.html") #./:현재폴더에서 folium.html을 저장, 위의 지도를 html형태로 저장됨
In [7]:
#!ls # !ls(윈도우,주피터노트북에서) : 'ls'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙니다.
In [35]:
#ls
tiles option : 지도가 나오는 스타일을 변경해주는 옵션¶
- tiles= ""
독스트링으로 확인
- "OpenStreetMap"
- "Mapbox Bright" (Limited levels of zoom for free tiles)
- "Mapbox Control Room" (Limited levels of zoom for free tiles)
- "Stamen" (Terrain, Toner, and Watercolor)
- "Cloudmade" (Must pass API key)
- "Mapbox" (Must pass API key)
- "CartoDB" (positron and dark_matter)
In [9]:
m = folium.Map(
location=[37.544564958079896, 127.05582307754338],
zoom_start=14,
tiles="OpenStreetMap" # 디폴트값
#tiles="Stamen" #오류 : 옵션없이 그냥 출력하면 오류뜸, ValueError: Built-in templates for Mapbox and Cloudmade have been removed. You can still use these providers by passing a URL to the `tiles` argument. See the documentation of the `TileLayer` class.
#tiles="Stamen Terrain" # 산악지대가 디테일하게 표현
#tiles="Stamen Toner" # 흑백 인쇄st 출력
#tiles="Stamen Watercolor" #물감느낌
#tiles="CartoDB positron" #옅은 회색
#tiles="CartoDB dark_matter" #아예 검은색
#tiles="Cloudmade" # 오류 (Must pass API key)
#tiles="Mapbox" # 오류 (Must pass API key)
#tiles="Mapbox Bright" #오류
#tiles="Mapbox Control Room" #오류
) # 0 ~ 18
m
Out[9]:
Make this Notebook Trusted to load map: File -> Trust Notebook
folium.Marker()¶
- 지도에 마커 생성
In [10]:
m = folium.Map(
location=[37.544564958079896, 127.05582307754338], # 성수역
zoom_start=14,
tiles="OpenStreetMap"
) # 0 ~ 18
# 뚝섬역
folium.Marker((37.54712311308356, 127.04721916917774)).add_to(m) # Marker()메소드, add_to(m): 기본지도에 마커추가
# 성수역
folium.Marker(
location=[37.544564958079896, 127.05582307754338],
popup="<b>Subway</b>" #popup="subway" : 클릭시 글자출력, <b>는 볼드체(html문법 적용가능)
).add_to(m)
# tooltip
folium.Marker(
location=[37.544564958079896, 127.05582307754338],
popup="<b>Subway</b>",
tooltip="<i>성수역</i>" #tooltip="" : 마우스를 갖다대면 성수역 출력, <i>는 이탤릭체
).add_to(m)
# Zerobase 강의장
folium.Marker(
location=[37.54558642069953, 127.05729705810472],
popup="<a href='https://zero-base.co.kr/' target=_'blink'>스쿨</a>", #a href:'홈페이지 주소',target=_'blink': 새창을 띄움
tooltip="<i>Zerobase 강의장</i>"
).add_to(m)
m
Out[10]:
Make this Notebook Trusted to load map: File -> Trust Notebook
In [11]:
m = folium.Map(
location=[37.544564958079896, 127.05582307754338], # 성수역
zoom_start=14,
tiles="OpenStreetMap"
) # 0 ~ 18
# icon basic
folium.Marker(
(37.54712311308356, 127.04721916917774),
icon=folium.Icon(color="black", icon='info-sign') #icon=folium.Icon #color="black"(디폴트값은 파랑), icon='info-sign'디폴트값
).add_to(m)
# icon icon_color
folium.Marker(
location=[37.544564958079896, 127.05582307754338],
popup="<b>Subway</b>",
tooltip="icon color",
icon=folium.Icon(
color="red", # 마커 색상
icon_color="pink", #구름안의 색상
icon="cloud") # 아이콘: 구름
).add_to(m)
# Icon custom
folium.Marker(
location=[37.54035903907497, 127.06913328776446], # 건대입구역
popup="건대입구역",
tooltip="Icon custom",
icon=folium.Icon(
color="purple",
icon_color="white",
#icon="bookmark",
#icon="android",
#icon="amazon",
#prefix="fa", #font awesome 홈페이지에서 무료아이콘은 prefix="fa"를 줘야 나타남
#icon="glyphicon glyphicon-cloud", #
angle=50, # 50도 기울임
prefix="glyphicon") # glyphicon
).add_to(m)
m
Out[11]:
Make this Notebook Trusted to load map: File -> Trust Notebook
folium.ClickForMarker()¶
- 지도위에 마우스로 클릭했을 때 마커를 생성해줍니다
In [12]:
m = folium.Map(
location=[37.544564958079896, 127.05582307754338], # 성수역
zoom_start=14,
tiles="OpenStreetMap"
) # 0 ~ 18
m.add_child(folium.ClickForMarker(popup="ClickForMarker"))
Out[12]:
Make this Notebook Trusted to load map: File -> Trust Notebook
folium.LatLngPopup()¶
- 지도를 마우스로 클릭했을 때 위도 경도 정보를 반환해줍니다
In [13]:
m = folium.Map(
location=[37.544564958079896, 127.05582307754338], # 성수역
zoom_start=14,
tiles="OpenStreetMap"
) # 0 ~ 18
m.add_child(folium.LatLngPopup())
Out[13]:
Make this Notebook Trusted to load map: File -> Trust Notebook
folium.Circle(), folium.CircleMarker()¶
- 지도에서 원형표시
In [14]:
m = folium.Map(
location=[37.55068861733562, 127.04420997492151], #성수역
zoom_start=14,
tiles="OpenStreetMap"
) # 0 ~ 18
# Circle
folium.Circle(
location=[37.555243442409406, 127.04370422643919], # 한양대학교
radius=100, #반지름
fill=True, #채움
color="#eb9e34", #구글에서 컬러피커 검색, 라인색상, 주황색
fill_color="red",
popup="Circle Popup",
tooltip="Circle Tooltip"
).add_to(m)
# CircleMarker : 서클과 서클마커 명확한 차이 공식문서에도 안나옴
folium.CircleMarker(
location=[37.54347089498245, 127.04439204503049], # 한양대학교
radius=100, #같은100을 넣어도 서클마커가 훨씬 큼
fill=True,
color="#34ebc6", #라인색상: 하늘색
fill_color="#c634eb", #보라색
popup="CircleMarker Popup",
tooltip="CircleMarker Tooltip"
).add_to(m)
m
Out[14]:
Make this Notebook Trusted to load map: File -> Trust Notebook
folium.Choropleth¶
- choropleth : 경계 그리는 메서드
- 색상이나 패턴을 사용하여 특정 통계에 대한 데이터를 사전 정의된 영역과 관련시켜 시각화 한 지도 유형
- Parameters
geo_data: string/object
URL, file path, or data (json, dict, geopandas, etc) to your GeoJSON
geometries
data: Pandas DataFrame or Series, default None
Data to bind to the GeoJSON.
columns: dict or tuple, default None
If the data is a Pandas DataFrame, the columns of data to be bound.
Must pass column 1 as the key, and column 2 the values.
key_on: string, default None
Variable in the `geo_data` GeoJSON file to bind the data to. Must
start with 'feature' and be in JavaScript objection notation.
Ex: 'feature.id' or 'feature.properties.statename'.
In [15]:
import json
In [16]:
state_data = pd.read_csv("data/02. US_Unemployment_Oct2012.csv") #2012년 10월 실업률 데이터
state_data.tail(2)
Out[16]:
State | Unemployment | |
---|---|---|
48 | WI | 6.8 |
49 | WY | 5.1 |
In [34]:
m = folium.Map([43, -102], zoom_start=3) #미국데이터라 미국 좌표를 찍어줌
folium.Choropleth( # 독스트링에서 상위 4개 옵션이 중요
geo_data="data/02. us-states.json", # 50개의 행마다 각 주의 경계선 좌표값이 담긴 형태의 데이터
data=state_data, # 판다스의 Series or DataFrame
columns=["State", "Unemployment"], # DataFrame columns # 실업율이 낮은 옅게, 실업율이 높으면 진하게
key_on="feature.id", #두 데이터를 묶어줌
fill_color="BuPu",
fill_opacity=1, # 0~1 투명도,1이 불투명
line_opacity=1, # 0~1
legend_name="Unemployment rate (%)" # 실업율이 낮은 옅게, 실업율이 높으면 진하게
).add_to(m)
m
Out[34]:
Make this Notebook Trusted to load map: File -> Trust Notebook
아파트 유형 지도 시각화¶
In [18]:
import pandas as pd
In [19]:
df = pd.read_csv("data/02.서울특별시 동작구_주택유형별 위치 정보 및 세대수 현황_20210825.csv",encoding="cp949") #euc-kr에서 좀 더 업그레이드된 버전
#df = pd.read_csv("data/02. 서울특별시 동작구_주택유형별 위치 정보 및 세대수 현황_20210825.csv", encoding="euc-kr") #한글로 인코딩
df.head()
Out[19]:
연번 | 분류 | 건물명 | 행정동 | 주소 | 세대수 | 위도 | 경도 | |
---|---|---|---|---|---|---|---|---|
0 | 1 | 아파트 | 노량진우성 | 노량진1동 | 서울특별시 동작구 만양로8길 50 | 901 | 37.510304 | 126.946866 |
1 | 2 | 아파트 | 노량진삼익 | 노량진1동 | 서울특별시 동작구 만양로 84 | 175 | 37.511367 | 126.945226 |
2 | 3 | 아파트 | 신동아리버파크\r(분양 1,696,임대 925) | 노량진1동 | 서울특별시 동작구 만양로 19 | 2621 | 37.507073 | 126.945718 |
3 | 4 | 아파트 | 노량진쌍용예가 | 노량진1동 | 서울특별시 동작구 장승배기로16길 134 | 299 | 37.510265 | 126.943676 |
4 | 5 | 아파트 | 형인한강 | 노량진1동 | 서울특별시 동작구 만양로 36 | 73 | 37.507664 | 126.948235 |
In [20]:
df.tail(2)
Out[20]:
연번 | 분류 | 건물명 | 행정동 | 주소 | 세대수 | 위도 | 경도 | |
---|---|---|---|---|---|---|---|---|
165 | 166 | 연립주택 | 능내연립 | 사당5동 | 서울특별시 동작구 사당로8길 39 | 22 | 37.483599 | 126.968672 |
166 | 167 | 연립주택 | 천록 | 대방동 | 서울특별시 동작구 등용로 43 | 29 | 37.505475 | 126.933434 |
In [21]:
df.info() #위도, 경도값이 갯수가 좀 빠져있음
<class 'pandas.core.frame.DataFrame'> RangeIndex: 167 entries, 0 to 166 Data columns (total 8 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 연번 167 non-null int64 1 분류 167 non-null object 2 건물명 167 non-null object 3 행정동 167 non-null object 4 주소 167 non-null object 5 세대수 167 non-null int64 6 위도 163 non-null float64 7 경도 163 non-null float64 dtypes: float64(2), int64(2), object(4) memory usage: 10.6+ KB
In [22]:
# NaN 데이터 제거 : 판다스의 dropna()함수 이용
# => 위도, 경도값 없는 데이터 삭제
df = df.dropna()
df.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 163 entries, 0 to 166 Data columns (total 8 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 연번 163 non-null int64 1 분류 163 non-null object 2 건물명 163 non-null object 3 행정동 163 non-null object 4 주소 163 non-null object 5 세대수 163 non-null int64 6 위도 163 non-null float64 7 경도 163 non-null float64 dtypes: float64(2), int64(2), object(4) memory usage: 11.5+ KB
In [23]:
# df.reset_index() : 데이터 재정렬, 인덱스가 컬럼으로 들어옴(drop=False, 디폴트값)
df = df.reset_index(drop=True) #drop=True:기본인덱스가 들어오지 않게함
df.tail(2)
Out[23]:
연번 | 분류 | 건물명 | 행정동 | 주소 | 세대수 | 위도 | 경도 | |
---|---|---|---|---|---|---|---|---|
161 | 166 | 연립주택 | 능내연립 | 사당5동 | 서울특별시 동작구 사당로8길 39 | 22 | 37.483599 | 126.968672 |
162 | 167 | 연립주택 | 천록 | 대방동 | 서울특별시 동작구 등용로 43 | 29 | 37.505475 | 126.933434 |
In [25]:
#del df["연번"] #KeyError: '연번', 한칸 띄어져 있음
In [26]:
df.columns
Out[26]:
Index(['연번 ', '분류 ', '건물명', '행정동', '주소', '세대수', '위도', '경도'], dtype='object')
In [27]:
df["연번 "]
Out[27]:
0 1 1 2 2 3 3 4 4 5 ... 158 163 159 164 160 165 161 166 162 167 Name: 연번 , Length: 163, dtype: int64
In [28]:
df = df.rename(columns={"연번 ": "연번", "분류 ": "분류"})
df.연번[:10]
Out[28]:
0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 Name: 연번, dtype: int64
In [29]:
df.tail(2)
Out[29]:
연번 | 분류 | 건물명 | 행정동 | 주소 | 세대수 | 위도 | 경도 | |
---|---|---|---|---|---|---|---|---|
161 | 166 | 연립주택 | 능내연립 | 사당5동 | 서울특별시 동작구 사당로8길 39 | 22 | 37.483599 | 126.968672 |
162 | 167 | 연립주택 | 천록 | 대방동 | 서울특별시 동작구 등용로 43 | 29 | 37.505475 | 126.933434 |
In [30]:
df.위도
Out[30]:
0 37.510304 1 37.511367 2 37.507073 3 37.510265 4 37.507664 ... 158 37.484815 159 37.489332 160 37.482790 161 37.483599 162 37.505475 Name: 위도, Length: 163, dtype: float64
In [31]:
df.위도[0]
Out[31]:
37.51030426
In [32]:
df.describe() #50%의 세대수(인구수): 199
#75%의 세대수 : 518.5
Out[32]:
연번 | 세대수 | 위도 | 경도 | |
---|---|---|---|---|
count | 163.000000 | 163.000000 | 163.000000 | 163.000000 |
mean | 84.153374 | 371.920245 | 37.497442 | 126.949817 |
std | 48.016276 | 413.115354 | 0.009532 | 0.019861 |
min | 1.000000 | 21.000000 | 37.477376 | 126.906940 |
25% | 43.500000 | 86.000000 | 37.490626 | 126.933284 |
50% | 84.000000 | 199.000000 | 37.496940 | 126.949902 |
75% | 125.500000 | 518.500000 | 37.505321 | 126.967196 |
max | 167.000000 | 2621.000000 | 37.514280 | 126.981966 |
In [33]:
# folium
m = folium.Map(location=[37.50589466533131, 126.93450729567374], zoom_start=13) #동작구
for idx, rows in df.iterrows(): #데이터프레임의 iterrows()함수: 한 행마다 한줄씩 받아서
#print(idx) #0~162, rows도 찍어보기
# location
lat, lng = rows.위도, rows.경도
# Marker
folium.Marker(
location=[lat, lng],
popup=rows.주소,
tooltip=rows.분류,
icon=folium.Icon(
icon="home",
color="lightred" if rows.세대수 >= 199 else "lightblue", #테두리컬러 #df.describe()dptj #50%의 세대수: 199
icon_color="darkred" if rows.세대수 >= 199 else "darkblue", #50%세대수(인구수)보다 크면 빨강, 작으면 파랑
)
).add_to(m)
# Circle
folium.Circle(
location=[lat, lng],
radius=rows.세대수 * 0.5, #세대수가 높으면 원크기가 크게, 낮으면 작게
fill=True,
color="pink" if rows.세대수 >= 518 else "green", #세대수가 많으면 핑크, 적으면 녹색
fill_color="pink" if rows.세대수 >= 518 else "green",
).add_to(m)
m
Out[33]:
Make this Notebook Trusted to load map: File -> Trust Notebook
'파이썬 라이브러리' 카테고리의 다른 글
Seaborn (0) | 2022.10.19 |
---|---|
Matplotlib (0) | 2022.10.19 |
Pandas 기초 (0) | 2022.10.14 |