반응형

이전에 folium을 활용하여 데이터를 시각화한 적이 있습니다. 하지만, folium을 활용하면 html 형태로 산출물이 나오기 때문에 다른 프로젝트(웹 등) 적용에는 용이하나, 보고서와 같이 A4에 쓰기에는 이미지 캡처를 해야 하고, 필요한 정보 이상이 들어오기 때문에 마음이 안 들수도 있을 것 같습니다.

 

https://seanpark11.tistory.com/52?category=916800 

 

[Folium] 파이썬을 활용한 지역별 월전력판매량 시각화하기

한전은 매달 전력통계월보를 발표한다. 해당 자료에는 여러가지 내용들이 반영되어 있는데, 그중에서 지역별 월전력판매량에 대해 한번 시각화를 해보려고 했고, leaflet.js에 기반한 파이썬 라이

seanpark11.tistory.com

 

이를 위해 찾아본 결과 matplotlib의 third-party 개념의 라이브러리(mpl-toolkits.basemap)가 있는데, 이를 해결하기에 꽤 괜찮아보여 시도해봤고 개인적으론 만족스러운 결과를 얻을 수 있어 공유하고자 합니다. 즉, 1) 좌표 정보를 갖고 있고, 2) 자신이 원하는 정보만 지도에 얹고 싶은 경우에 아래와 같은 사진의 결과를 얻을 수 있습니다.

 

이번 글의 목적은 다음과 같습니다.

  • 위 사진과 같은 지도이미지에 전세계에 위치한 발전소의 발전원별(색), 용량별(크기)로 분포도를 scatter plot
  • 여기서 전세계 위치는 위도, 경도로 확인 가능하여야 함

 

우선 간단히 코딩을 하기 위해 필요한 환경을 공유합니다. 여기서 특징은 이 라이브러리가 더이상 pip를 지원하지 않고 업데이트를 하지 않아 conda 환경에서 설치하고 사용해야 한다는 점입니다. 그러다보니, 설치가 쉽지 않을 수 있는데 그냥 아래처럼 버전을 맞추고, 가상환경을 설정해 진행하는 것을 추천합니다.

Version

Python = 3.8.5
pandas = 1.1.3
numpy = 1.21.3
matplotlib = 3.4.3
basemap = 1.2.2

보통 conda 환경에서 설치할 때는 "conda install [package]" 형태로 하게 되는데, 여기서는 아래 두가지로 설치하여야 하는 것으로 보입니다. 

conda install -c conda-forge basemap
conda install -c conda-forge proj

혹시 KeyError: 'PROJ_LIB'가 나온다면, 아래 접은 글을 확인해 주시기 바랍니다. (물론 밑에도 관련 코드 작성)

 

이렇게 설치가 완료되면, 데이터셋을 적재하고 코드를 실행하겠습니다. 데이터셋은 World Resources Institute에 Global Power Plant Database 를 csv로 제공하고 있습니다. 확보한 데이터셋을 파이썬 환경에 올리고, 코드에 필요한 라이브러리들을 불러오겠습니다.

 

여기서 scickit learn의 label encoder를 활용했는데, 이는 발전원 데이터(텍스트)를 색으로 구분하고, 이를 위해 필요한  인코딩을 수행했습니다.

# 1. Load the data
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from sklearn.preprocessing import LabelEncoder

global_power_df = pd.read_csv('global_power_plant_database.csv')

# Encooding with fuel types
le = LabelEncoder()
global_power_df['primary_fuel_encoded'] = le.fit_transform(global_power_df['primary_fuel'])

 

다음은 지도에 필요한 배경을 그리겠습니다. 아래 코드대로 작성하면, 처음에 봤던 세계전도같은 것이 global_m에 담기게 됩니다. 여기서 사이즈는 (160, 120)으로 설정하였는데, 적절한 크기로 설정하지 않으면 scatter plot의 버블이 지도에 비해 너무 커질 수도 있으니 주의하셔야 합니다..

 

# 2. Draw map background

fig = plt.figure(figsize=(160,120))
global_m = Basemap(projection="cyl", 
                   resolution=None, 
                   llcrnrlat=-90, 
                   urcrnrlat=90, 
                   llcrnrlon=-180, 
                   urcrnrlon=180)
global_m.shadedrelief()

 

이제 마지막으로 scatter plot으로 버블차트를 그립니다. Basemap이 기본적으로 matplotlib의 third-party이기 때문에 plt로 그려줄 수 있고, 아래처럼 코드로 구현이 가능합니다. 여기서 위에서 인코딩한 발전원별 데이터를 활용해 줍니다.

 

# 3. Scatter power location
global_m.scatter(global_power_df['longitude'], global_power_df['latitude'], latlon=True,
                c=global_power_df['primary_fuel_encoded'], s=global_power_df['capacity_mw'], 
                alpha=0.5)
cb = plt.colorbar(label ='primary_fuel', location='bottom')
cb.set_ticks([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14])
cb.set_ticklabels(['Biomass', 'Coal', 'CoGen', 'Gas', 'Geothermal', 'Hydro', 'Nuclear', 
                   'Oil', 'Other', 'Petcoke', 'Solar', 'Storage', 'Waste', 'Ocean', 'Wind'])
plt.show()

그리고 아래와 같은 결과를 얻었습니다. 다만, ticklabels의 경우 위 사이즈대로 하면 저렇게 크게 글자가 나오지 않아, 이 대신 잇몸이라고 선택한 방법은 한번은 사이즈를 크게, 다른 한번은 작게 해서 나온 두 이미지를 편집했습니다.

 

개인적으론 시각화 자체는 만족스러웠으나, 색을 colorbar로 활용하다보니, 인근에 있는 색과는 크게 구분되지 않는다는 단점이 있습니다. 이 부분은 나중에 버블 색을 지정해서 하는 방향으로 수정해서 시도해서 조금 더 눈에 잘 띄도록 할 필요가 있어 보입니다.

 


참고자료:

https://matplotlib.org/basemap/api/basemap_api.html

 

matplotlib basemap toolkit — Basemap Matplotlib Toolkit 1.2.1 documentation

Interpolate data (datain) on a rectilinear grid (with x = xin y = yin) to a grid with x = xout, y= yout. Note If datain is a masked array and order=1 (bilinear interpolation) is used, elements of dataout will be masked if any of the four surrounding points

matplotlib.org

https://wscode.tistory.com/9

 

[Python/Basemap]기상관측망 시각화

개발자 D 주제 : Basemap를 활용한 기상관측망 시각화 작업 데이터 : 종관기상관측(ASOS), 방재기상관측(AWS) 기상자료개방포털 ▶ 데이터 ▶ 메타데이터 ▶ 관측지점정보           (data.kma.go.kr/tme

wscode.tistory.com

https://jakevdp.github.io/PythonDataScienceHandbook/04.13-geographic-data-with-basemap.html

 

Geographic Data with Basemap | Python Data Science Handbook

Map Projections¶ The first thing to decide when using maps is what projection to use. You're probably familiar with the fact that it is impossible to project a spherical map, such as that of the Earth, onto a flat surface without somehow distorting it or

jakevdp.github.io

https://datasets.wri.org/dataset/globalpowerplantdatabase

 

Global Power Plant Database - Data | World Resources Institute

The Global Power Plant Database is a comprehensive, open source database of power plants around the world. It centralizes power plant data to make it easier to navigate, compare and draw insights...

datasets.wri.org

 

반응형