Python

Python - Basemap 이용하는 방법

electronicprogrammer 2020. 11. 8. 01:46

 

데이터 출처 : www.data.go.kr/tcs/dss/selectFileDataDetailView.do?publicDataPk=3038489

 

공공데이터 포털

국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Datase

www.data.go.kr

 

이번 포스팅에 대해서는 제가 그리고자 하는 부분을 Basemap 을 이용해서 출력하는 방법과 이 지도 위에 데이터를 시각화하는 방법에 대해서 정리해보도록 하겠습니다.

 

저는 위 공공데이터 포털에서 2019년에 일어난 교통사고 데이터를 이용해보도록 하겠습니다.

 

먼저 Pandas를 이용해서 데이터를 불러오겠습니다.

 

그리고 Basemap을 이용해서 대한민국을 그리기 위해서 먼저 Basemap 라이브러리를 먼저 불러오도록 하겠습니다.

from mpl_toolkits.basemap import Basemap as Basemap

 

이제 이 Basemap 을 이용해서 대한민국을 그려보겠습니다.

plt.figure(figsize=(15,10))

korea =  Basemap(projection='merc', 
                 lat_0=35.35, 
                 lon_0=128.58, 
                 resolution = 'h',
                 urcrnrlat=40, 
                 llcrnrlat=32, 
                 llcrnrlon=124.5, 
                 urcrnrlon=130.5)

korea.drawcoastlines()
korea.drawcountries()
korea.drawmapboundary()

plt.show()

lat_0 , long_0 으로 Basemap으로 그리고자 하는 지도 부분의 중심을 정합니다,

그리고 나서 ur은 upper right , ll 은 lower left 를 의미하는데 각각 오른쪽 위의 경도 및 위도를 정하고 왼쪽 아래의 경도 및 위도를 정해줍니다,

아래는 Basemap을 이용해서 그린 대한민국 입니다.

 

이제 교통사고에 대한 위치 정보를 이용해서 어떤 위치에 교통사고가 일어난 휫수에 대한 데이터를 저장해보도록 하겠습니다.

아래에 보시다시피 데이터에 위도 및 경도 데이터가 있습니다.

이 정보를 소숫점 3째 자리에서 반올림하고 해당 위치에서 교통사고가 일어난 횟수를 파악합니다.

df['lat'] = df['위도'].apply(lambda x : round(x, 2))
df['long'] = df['경도'].apply(lambda x : round(x, 2))

df['count'] = 0

for i in range(len(df)) :
    
    df.loc[i , 'count'] = df['사망자수'][i] + df['중상자수'][i]
    
geo_df = df[['lat' , 'long' , 'count']]

geo_df.head()

 

이제 이 데이터에 중복되는 위치가 있을 테니 중복되면 교통사고의 횟수를 더해주는 식으로 해서 데이터를 전처리해줍니다.

pos_Dict = {}

for i in range(len(geo_df)) :
    
    x = geo_df['long'][i]
    y = geo_df['lat'][i]
    
    pos = tuple([x,y])
    
    if pos not in pos_Dict.keys() :
        
        pos_Dict[pos] = geo_df['count'][i]
        
    else :
        
        pos_Dict[pos] += geo_df['count'][i]
        

 

아래는 pos_Dict에 관한 데이터입니다.

위치가 Key이고 (경도 , 위도) 로 되어있는 튜플입니다.

그리고 Value는 해당 위치에서 교통사고가 일어난 횟수입니다.

 

이제 이 위치 정보를 튜블로 되어있으니 경도 정보 리스트 , 그리고 위도 정보 리스트로 추출해서 저장해줍니다.

pos_List = list(pos_Dict.keys())

x_List = [pos[0] for pos in pos_List]
y_List = [pos[1] for pos in pos_List]

 

이제 저희는 경도 , 위도 그리고 교통사고 횟수를 파악하였으니 이를 앞서 그린 대한민국 지도에 시각화하고자 합니다.

plt.figure(figsize=(20,10))

korea =  Basemap(projection='merc', 
                 lat_0=35.35, 
                 lon_0=128.58, 
                 resolution = 'h',
                 urcrnrlat=40, 
                 llcrnrlat=32, 
                 llcrnrlon=124.5, 
                 urcrnrlon=130.5)

for i in range(len(pos_List)) :
    
    x = x_List[i]
    y = y_List[i]
    
    c = pos_Dict[pos_List[0]]
    
    # 필수 전처리 과정
    newX , newY = korea(x , y)
    
    plt.plot(newX , newY , 'ok' , markersize = c/5 , color = 'red')

korea.drawcoastlines()
korea.drawcountries()
korea.drawmapboundary()

plt.show()

 

아까와 같이 대한민국 지도를 그래고 그 위에 앞서 구한 위도 및 경도 데이터를 이용해서 해당 위치에 교통사고가 일어난 휫수에 따라서 점의 크기를 정해서 시각화 하고자 합니다. 단 주의할 점은 구한 위도 및 경도 데이터를 Basemap에 통과 시켜서 얻은 새로운 위치 좌표를 이용해서 시각화해야 한다는 점입니다.

 

아래는 최종적으로 시각화된 결과입니다.