[Python활용 공간분석] 서울시 상권(+카페업종) 시각화

Hyejin Beck·2023년 12월 10일

Python

목록 보기
3/23

서울시 Map

import requests
import json

# 서울 행정구역 json raw파일(githubcontent)
r = requests.get('https://raw.githubusercontent.com/southkorea/seoul-maps/master/kostat/2013/json/seoul_municipalities_geo_simple.json')
    
c = r.content
seoul_geo = json.loads(c)
                              # 각 구마다 어떻게 구성이 되어있는지 json형태로 확인가능, 
#seoul_geo                    # 일단 너무 길어서 주석처리함 
# 서울시 구별 바운더리 시각화 
m = folium.Map(
    location=[37.52408, 126.9802],     # 일단 서울시 용산구의 국립중앙박물관 경도,위도
    zoom_start=11,
)
 
folium.GeoJson(seoul_geo, name='지역구').add_to(m)
               #--------Json파일
      
m              # 바운더리 기준으로 표시됨

지도타입 변경

# 위의 지도 테마 변경   

m = folium.Map(
    location=[37.52408, 126.9802],     
    zoom_start=11,
    
    tiles='cartodbpositron',       # 타일변경 'CartoDB positron' 해도 똑같음 
)
 
folium.GeoJson(seoul_geo, name='지역구').add_to(m)
m

서울시 상권 데이터

소상공인시장진흥공단_상가(상권)정보

# 서울시 데이터 불러오기 
seoul = pd.read_csv('./learn/data20230930/소상공인시장진흥공단_상가(상권)정보_서울_202309.csv')

# 컬럼 확인 
print(seoul.columns)

# 필요 컬럼만 발췌 
seoul = seoul[['시군구명','상권업종대분류명','상권업종중분류명','위도','경도']]
seoul

# 서울시 업종별('상권업종중분류명') 갯수

seoul.상권업종중분류명.value_counts() # 많은 순에서부터 내림차순 

# 서울시 업종별('상권업종중분류명') 내림차순정렬에서 업종명만 발췌

seoul.상권업종중분류명.value_counts().index

# 서울시 업종별('상권업종중분류명') 갯수 시각화 

plt.figure(figsize=(5,10))
sns.countplot(y=seoul.상권업종중분류명);

# 서울시 업종별('상권업종중분류명') 갯수 시각화 --> 내림차순 

plt.figure(figsize=(10,20))
plt.yticks(fontsize=12)
plt.title('서울시 업종별 갯수(2023년 9월)')
sns.countplot(y=seoul.상권업종중분류명, order=seoul.상권업종중분류명.value_counts().index);

# 상권업종중분류명 컬럼의 앞뒤 공백 제거
seoul['상권업종중분류명'] = seoul['상권업종중분류명'].str.strip()
# '비알코올 ' --> '비알코올'

# 커피/카페 업종('비알코올')만 발췌 
seoul.loc[seoul['상권업종중분류명'] == '비알코올']

# 커피/카페 업종('비알코올')만 발췌 후, 자치구별 비교 
seoul.loc[seoul['상권업종중분류명'] == '비알코올'].groupby('시군구명')['상권업종대분류명'].count()

# 커피/카페 업종('비알코올')만 발췌 후, 자치구별 '오름차순'비교 
seoul.loc[seoul['상권업종중분류명'] == '비알코올'].groupby('시군구명')['상권업종대분류명'].count().sort_values()

# 커피/카페 업종('비알코올')만 발췌 후, 자치구별 '오름차순'비교 시각화 
seoul.loc[seoul['상권업종중분류명'] == '비알코올'].groupby('시군구명')['상권업종대분류명'].count().sort_values().plot(kind='bar')

# 커피/카페 업종('비알코올')만 발췌 후, 자치구별 '오름차순'비교 시각화 

plt.title('서울시 커피/카피/비알코올 자치구별 수(2023년 9월)')
seoul.loc[seoul['상권업종중분류명'] == '비알코올'].groupby('시군구명')['상권업종대분류명'].count().sort_values().plot(kind='barh');

서울시 지도 + 상권 데이터

# 지도 생성 
m = folium.Map(
    location=[37.52408, 126.9802], 
    zoom_start=11, 
    tiles='cartodbpositron',
)

folium.GeoJson(
    seoul_geo,
    name='지역구'
).add_to(m)

# m

# 클러스터 추가 
marker_cluster = MarkerCluster().add_to(m)

# 서울시 커피/카페/비알코올 데이터만 발췌 
seoul_coffee = seoul.loc[seoul['상권업종중분류명'] == '비알코올']

# 그 중 위도와 경도만 발췌하여 반복문으로 묶어서, 클러스터에 추가 
for lat, lng in zip(seoul_coffee['위도'],seoul_coffee['경도']): 
    folium.Marker([lat,lng], icon=folium.Icon(color='red')).add_to(marker_cluster)

m  

# 서울시 자치구별로 '비알코올'인 업종 갯수 확인

seoul_group_data = seoul.loc[seoul['상권업종중분류명']=='비알코올'].groupby('시군구명')['상권업종중분류명'].count()
seoul_group_data

카페업종에 한하여

# 서울시 자치구별로 '비알코올'인 업종 갯수에 따른 색상차이 맵시각화 

m = folium.Map(                            # 지도 셋팅 
    location=[37.52408, 126.9802], 
    zoom_start=11, 
    tiles='cartodbpositron'
)
                                           # Json파일(서울시 자치구별 위도,경도 데이터 추가) 
folium.GeoJson(
    seoul_geo, 
    name='지역구', 
).add_to(m)

m

참고로 seoul_geo 는 행정구별(강남구,송파구...등) 위도와 경도로 구분해놓은 json파일

# 서울시 행정구역 데이터 seoul_geo 가져와서 대입하기 

folium.Choropleth(
    geo_data=seoul_geo,            # 서울시 행정구역 표기된 json데이터 
    data = seoul_group_data,       # 서울시 자치구별 '비알코올' 업종 갯수
    fill_color='YlOrRd', 
    fill_opacity=0.5,              # 투명도 1짙음, 0흐림 
    line_opacity=0.2, 
    key_on = 'properties.name',    # seoul_geo의 properties 이름 지정 (다른 json파일에서는 properties가 아닐수 있으니 주의)
    legend_name = '지역구별 카페 업종 수'
).add_to(m)
m

카페업종에 한하여 백분율 4구간화

list(seoul_group_data.quantile([0, 0.25, 0.5, 0.75, 1 ]))    # 퍼센트로 4구간 나누어줌 

이렇게 하면 [390.0, 614.0, 800.0, 1025.0, 2083.0]
위의 수치값으로 4구간 나뉘어짐

# 위처럼 균등분할이 아닌, 4구간으로 나누어 퍼센트로 시각화 
bins = list(seoul_group_data.quantile([0, 0.25, 0.5, 0.75, 1 ]))

m = folium.Map(                            # 지도 셋팅 
    location=[37.52408, 126.9802], 
    zoom_start=11, 
    tiles='cartodbpositron'
)
                                           # Json파일(서울시 자치구별 위도,경도 데이터 추가) 
folium.GeoJson(
    seoul_geo, 
    name='지역구', 
).add_to(m)    

folium.Choropleth(
    geo_data=seoul_geo,            # 서울시 행정구역 표기된 json데이터 
    data = seoul_group_data,       # 서울시 자치구별 '비알코올' 업종 갯수
    fill_color='YlOrRd', 
    fill_opacity=0.5,              # 투명도 1짙음, 0흐림 
    line_opacity=0.2, 
    key_on = 'properties.name',    # seoul_geo의 properties 이름 지정 (다른 json파일에서는 properties가 아닐수 있으니 주의)
    legend_name = '지역구별 카페 업종 수', 

    bins = bins 
    
).add_to(m)
m

HTML로 저장

# HTML 파일로 저장 

m.save('map.html')

Copy Download Link

Copy Shareable Link

profile
데이터기반 스토리텔링을 통해 인사이트를 얻습니다.

0개의 댓글