- 개요
북극 진동 패턴은 다 계산했으니 최대한 NOAA에서 제공하는 그림과 비슷하게 그려봅니다.
길게 설명할 건 없고 그냥 코드로 들어가죠.
- NOAA 그림 따라 그리기
1. 칼라맵 따오기
뭐 어려운 건 없고 NOAA 그림을 캡쳐해서 그림판으로 연 다음
색 선택 >>> 색 편집으로 NOAA 그림 칼라맵 색상의 rgb값을 가져온겁니다.
colors에 저장하고 mcolors를 이용해서 custom_cmap으로 저장합니다.
import matplotlib.colors as mcolors
colors = [
(0.078431373, 0.392156863, 0.823529412), # -45 ~ -40
(0.156862745, 0.509803922, 0.941176471), # -40 ~ -35
(0.235294118, 0.588235294, 0.960784314), # -35 ~ -30
(0.31372549, 0.647058824, 0.960784314), # -30 ~ -25
(0.470588235, 0.725490196, 0.976470588), # -25 ~ -20
(0.588235, 0.823529, 0.976470588), # -20 ~ -15
(0.705882353, 0.941176471, 0.976470588), # -15 ~ -10 (7번째 색상)
(0.870588235, 1, 1), # -10 ~ -5
(1, 1, 1), # -5 ~ 5
(1, 0.976470588, 0.666666667), # 5 ~ 10
(1, 0.752941176, 0.235294118), # 10 ~ 15
(1, 0.376470588, 0), # 15 ~ 20
(0.882352941, 0.078431373, 0), # 20 ~ 25
]
custom_cmap = mcolors.ListedColormap(colors, name='custom_cmap')
2. 그림 그리기
저번에 그린 북극 진동 패턴 그림에서는 357.5도와 0도 사이 구역이 완전히 비어있었습니다.
제가 알기로 이를 따로 처리해주는 함수 같은 건 없고 경도의 차원을 1개 늘린 다음 처음 값을 넣어주면 매끄럽게 이어집니다.
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
fig, ax = plt.subplots(figsize=(10, 8), subplot_kw={'projection': ccrs.NorthPolarStereo()})
ax.coastlines(resolution='110m', linewidth=1, color='black')
levels = [-45, -40, -35, -30, -25, -20, -15, -10, -5, 5, 10, 15, 20, 25]
"""
lon의 끝부분에 360을 추가함
이를 newlon으로 정의
loadingMap도 첫 번째 열을 복제하여 끝에 추가
"""
newlon = []
for i in lon:
newlon.append(i)
newlon.append(360)
newLoadingMap = np.hstack([loadingMap, loadingMap[:, :1]])
"""
newLoadingMap에 minus를 곱해줘야 NOAA에서 그린 그림과 부호가 맞음
level 범위는 -45~25지만 vmin=-45로 하면 간격이 안 맞고 -46으로 해야함. 왜 그런지 모르겠음
"""
contourf = ax.contourf(newlon, lat, -newLoadingMap[:, :], transform=ccrs.PlateCarree(), cmap=custom_cmap, levels=levels, vmin=-46, vmax=25)
"""
그리드라인 선언
NOAA 그림과 완전히 똑같이 만들고 싶으면 gridlines를 쓰지 말고 선을 직접 그려야함
"""
from matplotlib.ticker import FixedLocator
gridlines = ax.gridlines(color='gray', linestyle=':', linewidth=0.5)
gridlines.xlocator = FixedLocator([-180, -150, -120, -90, -60, -30, 0, 30, 60, 90, 120, 150,180])
gridlines.ylocator = FixedLocator([20, 30, 40, 50, 60, 70, 80])
"""
첫 번째 모드(북극 진동)의 설명을 구하는 부분입니다.
EOF는 수학적으로 고유벡터 문제(eigenvector problem)를 푸는 것입니다.
북극 진동 패턴은 가장 큰 eigen value를 갖는 eigenvector와 동일합니다.
그래서 neigs=1 <<< 고유한 거 1개(eigen value의 내림차순으로 큰 거부터)만 뽑겠다.
"""
eofvar = solver.varianceFraction(neigs=1) * 100
plt.title(f'Leading EOF ({eofvar[0]:.0f}%) shown as\nregression map of 1000mb height (m)', fontsize=18)
cbar = fig.colorbar(contourf, ax=ax, orientation='vertical')
cbar.set_ticks(levels[1:-1])
cbar.set_ticklabels(levels[1:-1])
이 정도면 거의 똑같네요.
이것으로 북극 진동 패턴 계산 & 그리기 포스트는 마치겠습니다.
'대기과학 > 프로그래밍' 카테고리의 다른 글
[python, html/css] 안개 속보 화면 만들기: 2. 자료 다운로드와 처리 (4) | 2024.12.04 |
---|---|
[python, html/css] 안개 속보 화면 만들기: 1. 흐름 및 계획 (0) | 2024.12.03 |
[python] 북극 진동 (Arctic Oscillation) 패턴 계산 & 그리기 3: 북극 진동 패턴 구하기 (1) | 2024.11.18 |
[python] 북극 진동 (Arctic Oscillation) 패턴 계산 & 그리기 2: 자료 수집과 처리 (3) | 2024.11.15 |
[python] 북극 진동 (Arctic Oscillation) 패턴 계산 & 그리기 1: 목표 설정 (1) | 2024.11.14 |