- 개요
기후 나선에서는 시간에 따라 과거의 기온선부터 현재의 기온선까지 순차적으로 그려져야 합니다.
순차적으로 그리기 위해서는 애니메이션 효과를 써야하며, 그 전에 기온선을 그려야 합니다.
이번 포스트에서는 기온선을 그려보겠습니다.
- 모든 연도의 기온선 그리기
1. 선 그리기
선을 그리는 것은 어렵지 않습니다만
이전 포스트처럼 극좌표계의 위치를 기후나선에 맞게 수정을 해야합니다.
극좌표계에서 0도는 가장 오른쪽 방향이고, 각도가 증가할수록 반시계방향으로 돌아갑니다.
반면 기후나선에서는 극좌표계의 90도의 위치가 1월이고 2, 3, 4월은 시계방향의 순서로 위치합니다.
즉 시작하는 위치와 회전방향을 수정해줘야 합니다.
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib import cm
from matplotlib.colors import Normalize
PI = np.pi
YELLOW = (202/255.,183/255.,24/255.)
GREEN = (0., 176/255., 0.)
r_offset = 2.
str_month = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC' ]
fig = plt.figure(figsize=(7,7))
fig.patch.set_facecolor('black')
ax = fig.add_subplot()
ax.set_xlim(-6.5, 6.5)
ax.set_ylim(-6.5, 6.5)
ax.set_axis_off()
#----------------기온선 그리는 부분
theta = np.linspace(0+90, -360+90, 13)
theta = theta[:-1] # 반시계방향를 시계방향으로 변환
theta_plt = np.tile(theta, 70) # theta의 길이는 12으로 70년치를 그릴거라 70번 반복해야함
r = np.array(r) # 월평균 기온값을 r에 저장했었고 계산하기 편하게 np.array로 변환
print(type(theta_plt))
x = (r_offset + r) * np.cos(theta_plt / 180. * PI)
y = (r_offset + r) * np.sin(theta_plt / 180. * PI)
ax.plot(x, y)
#----------------
ax.text(0, -1 + r_offset, '-1\u00b0C', c=YELLOW, size=10, va= 'center', ha='center')
ax.text(0, 0 + r_offset, '0\u00b0C', c=GREEN, size=10, va= 'center', ha='center')
ax.text(0, 3.5 + r_offset, '+3.5\u00b0C', c=YELLOW, size=10, va= 'center', ha='center')
draw_text_month(ax, str_month, theta)
draw_circle(ax, r_offset, -1, 25., YELLOW)
draw_circle(ax, r_offset, 0, 15., GREEN)
draw_circle(ax, r_offset, 3.5, 8., YELLOW)
ax.text(0, 0, '2024', c='white', size=14, ha='center', va='center')
위의 그림은 기본색으로 모든 연도의 월평균 기온을 선으로 그린 것입니다.
하지만 기후나선 그림을 보면 선마다 색이 정해져 있습니다.
2. 선의 색 설정하기
기온을 기준으로 선의 색을 정해야합니다.
색을 정하는 과정에서 연평균 기온을 이용할수도 있고, 월평균 기온값마다 색을 정할 수 있습니다..
저는 선 하나를 만드는데 이용한 점 2개의 평균값으로 색을 정하겠습니다.
예를 들어 1월, 2월의 기온값으로 선을 만들었다면 1월과 2월의 평균 기온으로 색을 정합니다.
값에 따라 색을 반환하는 함수: get_color(value):
설명 그대로 value 값을 받으면 색을 반환함
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize
cmap = plt.get_cmap('coolwarm') # 파란색에서 빨간색까지의 colormap
norm = Normalize(vmin=-1.0, vmax=3.5) # -0.5에서 3.5 사이의 값을 normalize
def get_color(value):
"""특정 값에 대해 파란색에서 빨간색으로 선형 변화하는 색상 반환"""
if value < -1.0 or value > 3.5:
raise ValueError("Value should be between -0.5 and 3.5")
# 색상 맵핑 (정규화된 값을 colormap에 적용)
return cmap(norm(value))
나중에 애니메이션 작업을 위해 선을 하나씩 그리는 방식으로 작업하는 것이 좋습니다.
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib import cm
from matplotlib.colors import Normalize
PI = np.pi
YELLOW = (202/255.,183/255.,24/255.)
GREEN = (0., 176/255., 0.)
r_offset = 2.
str_month = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC' ]
fig = plt.figure(figsize=(7,7))
fig.patch.set_facecolor('black')
ax = fig.add_subplot()
ax.set_xlim(-6.5, 6.5)
ax.set_ylim(-6.5, 6.5)
ax.set_axis_off()
theta = np.linspace(0+90, -360+90, 13)
theta = theta[:-1]
theta_plt = np.tile(theta, 70)
r = np.array(r)
print(type(theta_plt))
'''
선마다 색을 지정해서 그리는 코드
x0, y0: 선의 시작점
x1, y1: 선의 끝점
'''
for i in range(len(r)-1):
x0 = (r_offset + r[i]) * np.cos(theta_plt[i] / 180. * PI)
y0 = (r_offset + r[i]) * np.sin(theta_plt[i] / 180. * PI)
x1 = (r_offset + r[i+1]) * np.cos(theta_plt[i+1] / 180. * PI)
y1 = (r_offset + r[i+1]) * np.sin(theta_plt[i+1] / 180. * PI)
color = get_color((r[i] + r[i+1])*0.5) # 시작점과 끝점의 평균값으로 색을 지정
ax.plot([x0, x1], [y0, y1], c=color)
ax.text(0, -1 + r_offset, '-1\u00b0C', c=YELLOW, size=10, va= 'center', ha='center')
ax.text(0, 0 + r_offset, '0\u00b0C', c=GREEN, size=10, va= 'center', ha='center')
ax.text(0, 3.5 + r_offset, '+3.5\u00b0C', c=YELLOW, size=10, va= 'center', ha='center')
draw_text_month(ax, str_month, theta)
draw_circle(ax, r_offset, -1, 25., YELLOW)
draw_circle(ax, r_offset, 0, 15., GREEN)
draw_circle(ax, r_offset, 3.5, 8., YELLOW)
ax.text(0, 0, '2024', c='white', size=14, ha='center', va='center')
다음 포스트에서는 선이 하나씩 그려지는 애니메이션 효과를 넣겠습니다.
'대기과학 > 프로그래밍' 카테고리의 다른 글
[python] 북극 진동 (Arctic Oscillation) 패턴 계산 & 그리기 0: 프롤로그 (1) | 2024.11.13 |
---|---|
[Matplotlib] 기후 나선 그리기 5: 애니메이션 만들기 (8) | 2024.10.11 |
[Matplotlib] 기후 나선 그리기 3: 밑그림 그리기 (1) | 2024.09.24 |
[Matplotlib] 기후 나선 그리기 2: 서울 일평균 기온 자료 전처리 (0) | 2024.09.20 |
[Matplotlib] 기후 나선 그리기 1: NASA Climate Change 그림 설명 및 사용할 자료 설명 (0) | 2024.09.19 |