- 개요
지금까지 제가 그린 그림의 축의 색은 모두 검정이었습니다.
이번 포스트에서는 각 변수에 맞는 색으로 y축과 y축의 라벨의 색을 바꾸어보겠습니다.
y축, yticklabel(라벨)의 위치는 아래 그림에서 확인해주세요.
기상청이 그린 AWS 그래프에서는 ytick의 길이를 0으로 설정하기 때문에 색 지정을 따로 할 필요는 없습니다.
- y축, tick, label 색 설정하기
먼저 y축, tick, label 색을 설정하는 메서드를 알아보겠습니다.
y축 색 설정 | y축 label 색 설정 |
ax.spines.right.set_color('red') 오른쪽 y축 ax.spines.left.set_color('red') 왼쪽 y축 |
ax.tick_params(axis='y', labelcolor=color) (양쪽 y축의 색을 바꾸지만 우리는 한쪽 y축에만 label을 그릴 것이라 상관없음) |
- plot의 기본설정에서는 왼쪽 y축, 오른쪽 y축을 그린다.
지금까지 그림을 그리는 코드를 확인해보시면
ax_base.plot으로 가장 처음 그래프를 그렸고,
ax_base에 twinx() 메서드를 사용해서 x축을 공유한 다음 새로운 그래프를 그립니다.
만약 여기에 색을 설정한다고 쳐봅시다.
ax_base에서는 왼쪽 y축을 빨강으로 설정하고
그 다음 twinx()로 선언한 ax에서 오른쪽 y축을 파랑으로 설정하면
아래와 같은 그림이 나옵니다.
왼쪽 y축의 색은 검정이고, 오른쪽 y축의 색은 파랑입니다.
그림이 그려지는 과정을 한 단계씩 보면
ax_base에서 왼쪽 y축은 빨강, 오른쪽 y축은 검정으로 그린 다음
그 위에 twinx()로 선언한 ax가 왼쪽 y축은 검정, 오른쪽 y축은 파랑으로 덮어씌우는 식으로 y축을 그립니다.
그러니 가장 먼저 그린 왼쪽의 빨강 y축이 보이지 않습니다.
그럼 이 문제를 어떻게 해결해야 할까요?
plot은 기본 설정으로 왼쪽, 오른쪽 y축을 그린다고 했으니 한 쪽축만 그리면 됩니다.
- y축에 색 입히기
기상청이 그린 AWS 그래프를 보시면 가장 안쪽의 y축 색은 회색입니다.
(왼쪽 y축에서 온도(T)는 빨강이지만 축은 회색, 오른쪽 y축에서 현지기압(P)은 분홍색이지만 축이 회색입니다.)
위에서도 말했지만 ytick의 길이는 0으로 설정해야합니다.
이런 점을 고려해서 코드를 짜보겠습니다.
import matplotlib.pyplot as plt
y_TA = df['TA']
y_PS = df['PS']
y_HM = df['HM']
y_WS = df['WS10']
y_WS[y_WS == -99.9] = np.NaN
y_RN15 = df['RN-15m']
y_RN60 = df['RN-60m']
y_RE = df['RE']*40
x = range(len(y_TA))
color_TA = 'red'
color_PS = (255./255., 51./255., 204./255.)
color_HM = (0, 102./255., 153/255.)
color_WS = (50./255., 108./255., 17./255.)
color_WD = (255./255., 153./255., 51./255.)
color_RN60 = (102./255., 153./255., 1.)
color_RN15 = (1., 153./255., 1.)
color_RE = (204./255., 255./255., 255./255.)
fig = plt.figure(figsize=(13,5))
# RN60, RN15
ax_base = fig.add_subplot()
dx = x[1] - x[0]
ax_base.bar(x, y_RE, color=color_RE, width=dx)
ax_base.bar(x, y_RN60, color=color_RN60, width=dx)
ax_base.bar(x, y_RN15, color=color_RN15, width=dx)
ymin, ymax, dy = 0, 40, 4
ax_base.set_ylim(ymin, ymax)
ax_base.set_yticks(range(ymin, ymax+1, dy))
ax_base.spines.left.set_position(('outward', 70)) # 왼쪽 y축의 위치 조정
ax_base.spines.right.set_visible(False) # 오른쪽 y축은 그리지 않음
ax_base.yaxis.set_ticks_position('left') # ytick을 왼쪽에 그림
ax_base.yaxis.set_label_position('left') # ylabel을 왼쪽에 그림
ax_base.spines.left.set_color(color_RN60) # 왼쪽 y축 색 설정
ax_base.spines.left.set_linewidth(2) # 왼쪽 y축의 선 두께 설정
ax_base.tick_params(axis='y', which='both', length=0) # y축의 major, minor(whici='both') tick의 길이를 0으로 설정
ax_base.tick_params(axis='y', labelcolor=color_RN60) # ylabel 색 설정
# 온도
color = color_TA
ax = ax_base.twinx()
ax.plot(x, y_TA, color=color, lw=1)
ymin, ymax = 16, 36
ax.set_ylim(ymin, ymax)
ax.set_yticks(range(ymin, ymax+1, 2))
ax.spines.right.set_visible(False)
ax.yaxis.set_ticks_position('left')
ax.yaxis.set_label_position('left')
ax.spines.left.set_color('gray')
ax.spines.left.set_linewidth(2)
ax.tick_params(axis='y', which='both', length=0)
ax.tick_params(axis='y', labelcolor=color)
# 현지기압
color = color_PS
ax = ax_base.twinx()
ax.plot(x, y_PS, color=color, lw=1)
ax.set_ylim(999, 1019)
ax.set_yticks(range(999, 1019+1, 2))
ax.spines.left.set_visible(False)
ax.spines.right.set_color('gray')
ax.spines.right.set_linewidth(2)
ax.tick_params(axis='y', which='both', length=0)
ax.tick_params(axis='y', labelcolor=color)
# 습도
color = color_HM
ax = ax_base.twinx()
ax.plot(x, y_HM, color=color, lw=1)
ax.set_ylim(0, 100)
ax.set_yticks(range(0, 100+1, 10))
ax.spines.right.set_position(('outward', 35))
ax.spines.left.set_visible(False)
ax.spines.right.set_color(color)
ax.spines.right.set_linewidth(2)
ax.tick_params(axis='y', which='both', length=0)
ax.tick_params(axis='y', labelcolor=color)
# 풍속
color = color_WS
ax = ax_base.twinx()
ax.plot(x, y_WS, color=color, lw=1)
ax.set_ylim(0, 20)
ax.set_yticks(range(0, 20+1, 2))
ax.spines.left.set_position(('outward', 25))
ax.spines.right.set_visible(False)
ax.yaxis.set_ticks_position('left')
ax.yaxis.set_label_position('left')
ax.spines.left.set_color(color)
ax.spines.left.set_linewidth(2)
ax.tick_params(axis='y', which='both', length=0)
ax.tick_params(axis='y', labelcolor=color)
# 풍향
y_WD = df['WD10']
df.loc[df['WD10'] < 90, 'WD10'] += 360
color = color_WD
ax = ax_base.twinx()
ax.scatter(x, y_WD, color=color, s=4)
ax.set_ylim(90, 90+360)
ax.set_yticks(range(90, 90+360+1, 90))
ax.spines.left.set_position(('outward', 50))
ax.spines.right.set_visible(False)
ax.yaxis.set_ticks_position('left')
ax.yaxis.set_label_position('left')
ax.set_yticklabels(['E', 'S', 'W', 'N', 'E'])
ax.spines.left.set_color(color)
ax.spines.left.set_linewidth(2)
ax.tick_params(axis='y', which='both', length=0)
ax.tick_params(axis='y', labelcolor=color)
y축이 6개이기 때문에 ax_base를 1번, twinx()를 5번 선언해서 그림을 그리고 있습니다.
twinx()를 5번 반복하는데 저는 코드를 그대로 복붙하고 있으므로 같은 형식의 코드가 5번 반복됩니다.
이 부분은 for문으로 만들면 훨씬 코드가 간결해지고, 나중에 자동화하기도 쉽습니다.
다음 포스트에서는 5번 반복되는 twinx() 부분을 for문으로 만들어서 그림을 그려보겠습니다.
'대기과학 > 프로그래밍' 카테고리의 다른 글
[Matplotlib] 기상청 ASOS/AWS 그래프 따라 그리기 6: y축 제목, 단위 적기 (2) | 2024.07.23 |
---|---|
[Matplotlib] 기상청 ASOS/AWS 그래프 따라 그리기 5: 반복하는 부분을 for문으로 만들기 (0) | 2024.07.19 |
[Matplotlib] 기상청 ASOS/AWS 그래프 따라 그리기 3: 선과 음영 그리기 (1) | 2024.07.12 |
[Matplotlib] 기상청 ASOS/AWS 그래프 따라 그리기 2: 왼쪽에 y축 여러 개 그리기 (0) | 2024.07.11 |
[Matplotlib] 기상청 ASOS/AWS 그래프 따라 그리기 1: 오른쪽에 y축 여러 개 그리기 (0) | 2024.07.10 |