(12주차) 11월29일
Choropleth Map, 판다스백엔드
- (1/10) Choropleth Map (1)
- (2/10) Choropleth Map (2)
- (3/10) Choropleth Map (3)
- (4/10) folium: 한국지도 그리기
- (5/10) plotly: 한국지도 그리기 (1)
- (6/10) plotly: 한국지도 그리기 (2)
- (7/10) pandas_datareader
- (8/10) 판다스백엔드 line
- (9/10) 판다스백엔드 bar (1)
- (10/10) 판다스백엔드 bar (2)
import folium
import pandas as pd
import json
import requests
local_distriction_jsonurl='https://raw.githubusercontent.com/southkorea/southkorea-maps/master/kostat/2018/json/skorea-municipalities-2018-geo.json'
global_distriction_jsonurl='https://raw.githubusercontent.com/southkorea/southkorea-maps/master/kostat/2018/json/skorea-provinces-2018-geo.json'
local_dict = json.loads(requests.get(local_distriction_jsonurl).text)
global_dict = json.loads(requests.get(global_distriction_jsonurl).text)
- 잔뜩 복잡해보이는 파일이 일단 dict형태로 있음.
- 지역을 global scale로 시각화.
m = folium.Map([36,128],zoom_start=7,scrollWheelZoom=False)
folium.Choropleth(geo_data=global_dict).add_to(m)
#m
- 지역을 local scale로 시각화
m = folium.Map([36,128],zoom_start=7,scrollWheelZoom=False)
folium.Choropleth(geo_data=local_dict).add_to(m)
#m
- local_dict 를 살펴보자.
local_dict?
- 4개의 원소를 가지는 딕셔너리
- 원소의 이름은 아래와 같이 확인가능
local_dict.keys()
- type, features, name, crs
- type, name, crs 부터 살펴보자.
local_dict['type']
local_dict['name']
local_dict['crs']
- 위의 3개는 특별한것이 없어보임. 이제 features를 살펴보자.
_features = local_dict['features']
- 길이가 250인 list
- 250의 리스트는 각각의 구(혹은 군,시)를 의미하는것 같다.
_features[0] # 첫번째 구
- 첫번째 구는 다시 3개의 원소로 구성된 딕셔너리
_features[0]['type']
_features[0]['geometry']
_features[0]['properties']
- _features[0] 는 다시 dict 타입이다. 길이가3, 키는 type, geometry, properties 이다. 이중에서 type은 별 정보가 없고 geometry에는 멀티폴리곤 지옴에 대한 좌표값이 정리되어있다. 그리고 properties에는 이름, 영문이름, 코드와 같은 정보들이 정리되어 있다.
_features[200]['properties']['name']
- 덕진과와 완산구를 찾아보자.
_lst =[_features[i]['properties']['name'] for i in range(250)]
_lst[:10]
- 전주시완산구, 전주시덕진구가 있다. (도시의 크기에 따라서 구/군/시 등으로 표기됨)
- 전주시완산구, 전주시덕진구가 _lst의 몇번째에 위치할까?
(예비학습) 리스트에서 특정 원소가 위치한 인덱스를 알아내는 방법 (where)
['a','b','c'].index('c')
예비학습끝
_lst.index('전주시덕진구')
_lst.index('전주시완산구')
_lst.index(['전주시완산구','전주시덕진구'])
_keywords=['전주시완산구','전주시덕진구']
[_lst.index(_keywords[i]) for i in range(2)] # 구식프로그래밍
_keywords=['전주시완산구','전주시덕진구']
[_lst.index(i) for i in _keywords] #신식(?)프로그래밍
_keywords=['전주시완산구','전주시덕진구']
[_lst.index(keyword) for keyword in _keywords] # 가독성향상
[_lst.index(keyword) for keyword in ['전주시완산구','전주시덕진구']] # compact
- local_dict와 형식은 똑같은데 덕진구와 완산구만 포함한 local_dict2를 만들자.
(예비학습) VIEW vs COPY
dict1= {'a':1, 'b':2, 'c':3}
dict1
dict2=dict1
dict2
dict2['b']=5
dict2
dict1
- 또 이상한 일이 생김.
- 이러한 현상을 피하기 위해서는 dict2가 dict1의 카피임을 명시해야 한다. (현재는 dict2가 dict1의 바로가기 아이콘같은 존재)
dict1= {'a':1, 'b':2, 'c':3}
dict2=dict1.copy()
dict2['b']=5
print(dict1)
print(dict2)
- 카피임을 명시하니까 문제가 없어짐
(예비학습끝)
local_dict2 = local_dict.copy()
local_dict2.keys()
_keywords=['전주시완산구','전주시덕진구']
_jj = [_lst.index(keyword) for keyword in _keywords]
_jj
local_dict2['features'] = [local_dict['features'][j] for j in _jj]
m = folium.Map([36,128],zoom_start=7,scrollWheelZoom=False)
folium.Choropleth(geo_data=local_dict2).add_to(m)
#m
- 좀 더 크게 + 위치조정 (전주시를 중심으로)
m = folium.Map([35.84195368311022, 127.1155556693179],zoom_start=11,scrollWheelZoom=False)
folium.Choropleth(geo_data=local_dict2).add_to(m)
#m
- 아래와 같은 그림에서 덕진구와 완산구의 어떠한 value를 비교하고 싶음 (카카오바이크 등)
m = folium.Map([35.84195368311022, 127.1155556693179],zoom_start=11,scrollWheelZoom=False)
folium.Choropleth(geo_data=local_dict2).add_to(m)
#m
- 선실습, 후설명
df = pd.DataFrame({'key':['전주시덕진구','전주시완산구'],'value':[20,30]})
df
m = folium.Map([35.84195368311022, 127.1155556693179],zoom_start=11,scrollWheelZoom=False)
choro = folium.Choropleth(
data=df,
geo_data=local_dict2,
columns=['key','value'],
key_on = 'feature.properties.name'
)
choro.add_to(m)
#m
- folium.Choropleth 의 사용법
(이해를 위해 필요한 약간의 직관)
- 뭔가 2개의 데이터를 연결해야하는 구조이다. 하나는 df, 다른하나는 json에서 나온 dict (local_dict2) 이다.
- 데이터를 연결하기 위해서는 공유가능한 연결의 매개체가 필요하다. (cbind: row-index를 공유, rbind: colnames공유, merge: 양쪽 데이터프레임에서 같은 이름을 가진 특정 col이 있었음)
- 연결의 매개체는 df와 local_dict2에 각각 존재하는데, df에서는
key라는 이름의 칼럼으로 저장했었고 local_dict2 에서는local_dict2['features'][?]['properties']['name']에 있다.
local_dict2['features'][0]['properties']['name']
(사용법)
choro = folium.Choropleth(
data=df, ## data1
geo_data=local_dict2, ## data2 (이 시점에서 폴리곤에 대한 정보가 choro 인스턴스에 전달)
columns=['key','value'], ## data1에서 중요한것들을 나열. 항상 [key,value]의 조합으로 써야한다.
# 이때 ['key','value']는 [data2와의 매개체,지도에서 색의 단계를 표현하는 변수]로 해석가능
key_on = 'feature.properties.name' ## data2에서 중요한것: 즉 data1과의 연결매개체
)
folium.Choropleth 의 key_on 파라메터는 (1) 항상 feature로 시작하고 (2) 이후는에는 local_dict2[’features’][?]의 하위에 data1과 매칭되는 path를 찾음
local_dict2['features'][0]['properties']['name']
- 당연히 영문이름을 매개체로 쓸 수 있다.
local_dict2['features'][0]['properties']['name_eng']
df = pd.DataFrame({'key':['전주시덕진구','Jeonjusiwansangu'],'value':[20,30]})
df
m = folium.Map([35.84195368311022, 127.1155556693179],zoom_start=11,scrollWheelZoom=False)
choro = folium.Choropleth(
data=df,
geo_data=local_dict2,
columns=['key','value'],
key_on = 'feature.properties.name'
)
choro.add_to(m)
#m
m = folium.Map([35.84195368311022, 127.1155556693179],zoom_start=11,scrollWheelZoom=False)
choro = folium.Choropleth(
data=df,
geo_data=local_dict2,
columns=['key','value'],
key_on = 'feature.properties.name_eng'
)
choro.add_to(m)
#m
- 한글이름, 영문이름 뿐만이 아니라 code를 key_on으로 쓸 수 있음.
local_dict2['features'][0]['properties']
local_dict2['features'][1]['properties']
df = pd.DataFrame({'key':['35012','35011'],'value':[20,30]})
df
m = folium.Map([35.84195368311022, 127.1155556693179],zoom_start=11,scrollWheelZoom=False)
choro = folium.Choropleth(
data=df,
geo_data=local_dict2,
columns=['key','value'],
key_on = 'feature.properties.code'
)
choro.add_to(m)
#m
df=pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/2021-11-22-prov.csv')
df
m = folium.Map([35.84195368311022, 127.1155556693179],zoom_start=6,scrollWheelZoom=False)
choro= folium.Choropleth(
data=df,
geo_data= global_dict,
columns=['행정구역(시군구)별','총인구수 (명)'],
key_on='feature.properties.name'
)
choro.add_to(m)
#m
df=pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/2021-11-22-muni.csv')
df
m = folium.Map([35.84195368311022, 127.1155556693179],zoom_start=7,scrollWheelZoom=False)
choro= folium.Choropleth(
data=df,
geo_data= local_dict,
columns=['행정구역(시군구)별','총인구수 (명)'],
key_on='feature.properties.name'
)
choro.add_to(m)
#m
import plotly.express as px
from IPython.display import HTML
df = px.data.election()
geojson = px.data.election_geojson()
fig = px.choropleth_mapbox(df, geojson=geojson, color="Bergeron",
locations="district", featureidkey="properties.district",
center={"lat": 45.5517, "lon": -73.7073},
mapbox_style="carto-positron", zoom=9)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
HTML(fig.to_html(include_plotlyjs='cdn',include_mathjax=False, config=dict({'scrollZoom':False})))
#fig.show(config=dict({'scrollZoom':False}))
- 공식홈페이지의 예제를 뜯어보자.
df.head()
- properties의 district 혹은 id를 key로 한다.
- 코드를 다시 관찰하자.
df = px.data.election() ### 일반적인 데이터 프레임
geojson = px.data.election_geojson() ### json파일
fig = px.choropleth_mapbox(df, ### 데이터프레임
geojson=geojson, ### json파일
color="Bergeron", ### df에서 코로플레스의 단계를 표시
locations="district", ### df에 존재하는 연결변수
featureidkey="properties.district", ### json에 존재하는 연결매개체
center={"lat": 45.5517, "lon": -73.7073},
mapbox_style="carto-positron",
zoom=9)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.show(config=dict({'scrollZoom':False}))
- 우리의 상황으로 바꾸면
df=pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/2021-11-22-prov.csv')
df
geojson = global_dict ### json파일
fig = px.choropleth_mapbox(df, ### 데이터프레임
geojson=geojson, ### json파일
color="총인구수 (명)", ### df에서 코로플레스의 단계를 표시
locations="행정구역(시군구)별", ### df에 존재하는 연결변수
featureidkey="properties.name", ### json에 존재하는 연결매개체
center={"lat": 35.84195368311022, "lon": 127.1155556693179},
mapbox_style="carto-positron",
zoom=5)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
HTML(fig.to_html(include_plotlyjs='cdn',include_mathjax=False, config=dict({'scrollZoom':False})))
import numpy as np
import pandas as pd
import warnings
from IPython.display import HTML
from pandas_datareader import data as pdr
def show(fig):
return HTML(fig.to_html(include_plotlyjs='cdn',include_mathjax=False, config=dict({'scrollZoom':False})))
symbols = ['AMZN','AAPL','GOOG','MSFT','NFLX','NVDA','TSLA']
start = '2020-01-01'
end = '2020-11-28'
df = pdr.get_data_yahoo(symbols,start,end)['Adj Close']
df
df.reset_index()
- 1개의 y를 그리기
df.reset_index().plot.line(x='Date',y='AMZN')
- 2개의 y를 겹쳐그리기
df.reset_index().plot.line(x='Date',y=['AMZN','GOOG'])
- 모든 y겹처그리기
df.reset_index().plot.line(x='Date')
- 그림크기 조정
df.reset_index().plot.line(x='Date',figsize=(10,10))
- 서브플랏
df.reset_index().plot.line(x='Date',figsize=(10,10),subplots=True)
- 레이아웃 조정
df.reset_index().plot.line(x='Date',figsize=(10,10),subplots=True,layout=(4,2))
- 폰트조정
df.reset_index().plot.line(x='Date',figsize=(10,10),subplots=True,layout=(4,2),fontsize=20)
- 투명도 조정
df.reset_index().plot.line(x='Date',figsize=(10,10),subplots=True,layout=(4,2),alpha=0.3)
- 레전드 삭제
df.reset_index().plot.line(x='Date',figsize=(10,10),subplots=True,layout=(4,2),legend=False)
df = pd.read_csv('https://raw.githubusercontent.com/kalilurrahman/datasets/main/mobilephonemktshare2020.csv')
df
df.plot.bar(x='Date',y=['Samsung','Apple'],figsize=(10,5))
df.plot.bar(x='Date',y=['Samsung','Apple'],figsize=(10,5),width=0.8)
df.plot.barh(x='Date',y=['Samsung','Apple'],figsize=(5,10))
- 그림이 별로임
df.plot.bar(x='Date',figsize=(15,10),subplots=True,layout=(4,4),legend=False)
- 이건 사실 라인플랏으로 그려도 괜찮음
- 비율을 평균내는 것은 이상하지만 시각화예제를 위해서 제조사별로 평균점유율을 시각화하여보자.
df.melt(id_vars='Date').groupby('variable').agg(np.mean).\
plot.bar(legend=False)
- 소팅을 한뒤에 시각화해보자.
df.melt(id_vars='Date').groupby('variable').agg(np.mean).sort_values('value',ascending=False).\
plot.bar(legend=False)
fig= df.melt(id_vars='Date').groupby('variable').agg(np.mean).sort_values('value',ascending=False).\
plot.bar(backend='plotly')
show(fig)
fig=df.melt(id_vars='Date').\
plot.bar(x='Date',y='value',color='variable',backend='plotly',width=500,height=600)
show(fig)
fig=df.melt(id_vars='Date').query("variable=='Samsung' or variable=='Apple' or variable=='Huawei'").\
plot.bar(x='Date',y='value',color='variable',backend='plotly',barmode='group')
show(fig)
fig=df.melt(id_vars='Date').query("variable=='Samsung' or variable=='Apple' or variable=='Huawei'" ).\
plot.bar(x='Date',y='value',color='variable',backend='plotly',barmode='group',text='value')
show(fig)
fig=df.melt(id_vars='Date').query("variable=='Samsung' or variable=='Apple' or variable=='Huawei'" ).\
plot.bar(x='Date',y='value',color='variable',backend='plotly',facet_col='variable')
show(fig)
fig=df.melt(id_vars='Date').query("variable=='Samsung' or variable=='Apple' or variable=='Huawei'" ).\
plot.bar(y='Date',x='value',color='variable',backend='plotly',facet_row='variable',height=700)
show(fig)