소개
Matplotlib 는 Python 을 위한 강력한 데이터 시각화 라이브러리입니다. 데이터 플로팅을 위한 여러 내장 스케일을 제공하지만, 특정 사용 사례에 맞게 사용자 정의 스케일이 필요한 경우가 있습니다. 이 랩에서는 위도 데이터에 Mercator 투영법 (Mercator projection) 을 사용하는 사용자 정의 스케일을 만드는 방법을 보여드리겠습니다.
VM 팁
VM 시작이 완료되면, 왼쪽 상단을 클릭하여 Notebook 탭으로 전환하여 실습을 위해 Jupyter Notebook에 접속하십시오.
때로는 Jupyter Notebook 이 로딩을 완료하는 데 몇 초 정도 기다려야 할 수 있습니다. Jupyter Notebook 의 제한 사항으로 인해 작업의 유효성 검사는 자동화될 수 없습니다.
학습 중에 문제가 발생하면 Labby 에게 문의하십시오. 세션 후 피드백을 제공해주시면 문제를 신속하게 해결해 드리겠습니다.
필요한 라이브러리 임포트
필요한 라이브러리를 임포트하는 것으로 시작합니다.
import numpy as np
from numpy import ma
from matplotlib import scale as mscale
from matplotlib import transforms as mtransforms
from matplotlib.ticker import FixedLocator, FuncFormatter
MercatorLatitudeScale 클래스 정의
다음으로, 사용자 정의 스케일을 구현할 MercatorLatitudeScale 클래스를 정의합니다. 이 클래스는 mscale.ScaleBase를 상속받습니다.
class MercatorLatitudeScale(mscale.ScaleBase):
"""
Mercator 투영법에서 위도를 스케일링하는 데 사용되는 시스템을 사용하여 -pi/2에서 pi/2 (-90 도에서 90 도) 범위의 데이터를 스케일링합니다.
스케일 함수:
ln(tan(y) + sec(y))
역 스케일 함수:
atan(sinh(y))
Mercator 스케일은 +/- 90 도에서 무한대로 향하는 경향이 있으므로,
아무것도 플로팅되지 않는 사용자 정의 임계값이 있습니다. 이는 기본적으로 +/- 85 도입니다.
__ https://en.wikipedia.org/wiki/Mercator_projection
"""
MercatorLatitudeTransform 클래스 구현
MercatorLatitudeScale 클래스 내에서 데이터를 실제로 변환할 MercatorLatitudeTransform 클래스를 정의합니다. 이 클래스는 mtransforms.Transform을 상속받습니다.
class MercatorLatitudeTransform(mtransforms.Transform):
## 정의해야 하는 두 개의 값 멤버가 있습니다.
## ``input_dims`` 및 ``output_dims`` 는 변환에 대한 입력
## 차원 수와 출력 차원 수를 지정합니다.
## 이는 변환 프레임워크에서 일부
## 오류 검사를 수행하고 호환되지 않는 변환이
## 함께 연결되는 것을 방지하는 데 사용됩니다. 스케일에 대한 변환을 정의할 때,
## 이는 정의상 분리 가능하며 차원이 하나만 있으므로,
## 이러한 멤버는 항상 1 로 설정해야 합니다.
input_dims = output_dims = 1
def __init__(self, thresh):
mtransforms.Transform.__init__(self)
self.thresh = thresh
def transform_non_affine(self, a):
"""
이 변환은 numpy 배열을 가져와 변환된 복사본을 반환합니다.
Mercator 스케일의 범위는 사용자가 지정한 임계값으로 제한되므로,
입력 배열은 유효한 값만 포함하도록 마스킹되어야 합니다. Matplotlib 는 마스킹된 배열을 처리하고
범위를 벗어난 데이터를 플롯에서 제거합니다. 그러나,
반환된 배열은 입력 배열과 동일한 모양을 *가져야* 합니다.
이러한 값은 다른 차원의 값과 동기화된 상태로 유지되어야 하기 때문입니다.
"""
masked = ma.masked_where((a < -self.thresh) | (a > self.thresh), a)
if masked.mask.any():
return ma.log(np.abs(ma.tan(masked) + 1 / ma.cos(masked)))
else:
return np.log(np.abs(np.tan(a) + 1 / np.cos(a)))
def inverted(self):
"""
Matplotlib 가 이 변환에 대한 역변환을 얻는 방법을 알 수 있도록
이 메서드를 재정의합니다.
"""
return MercatorLatitudeScale.InvertedMercatorLatitudeTransform(
self.thresh)
InvertedMercatorLatitudeTransform 클래스 구현
또한 이 스케일에 대한 역변환을 얻는 데 사용될 InvertedMercatorLatitudeTransform 클래스를 정의합니다.
class InvertedMercatorLatitudeTransform(mtransforms.Transform):
input_dims = output_dims = 1
def __init__(self, thresh):
mtransforms.Transform.__init__(self)
self.thresh = thresh
def transform_non_affine(self, a):
return np.arctan(np.sinh(a))
def inverted(self):
return MercatorLatitudeScale.MercatorLatitudeTransform(self.thresh)
사용자 정의 스케일 등록
mscale.register_scale을 사용하여 Matplotlib 에 사용자 정의 스케일을 등록합니다.
mscale.register_scale(MercatorLatitudeScale)
사용자 정의 스케일 사용
이제 플롯에서 사용자 정의 스케일을 사용할 수 있습니다. 다음은 Mercator 투영법에서 위도 데이터에 사용자 정의 스케일을 사용하는 예입니다.
if __name__ == '__main__':
import matplotlib.pyplot as plt
t = np.arange(-180.0, 180.0, 0.1)
s = np.radians(t)/2.
plt.plot(t, s, '-', lw=2)
plt.yscale('mercator')
plt.xlabel('Longitude')
plt.ylabel('Latitude')
plt.title('Mercator projection')
plt.grid(True)
plt.show()
요약
이 랩에서는 위도 데이터에 대한 Mercator 투영법을 사용하여 Matplotlib 에서 사용자 정의 스케일을 만드는 방법을 배웠습니다. MercatorLatitudeScale 및 MercatorLatitudeTransform 클래스를 정의하고 mscale.register_scale을 사용하여 사용자 정의 스케일을 Matplotlib 에 등록했습니다. 또한 Mercator 투영법에서 위도 데이터에 사용자 정의 스케일을 사용하는 예시를 보여주었습니다.