[Matplotlib] 기상청 ASOS/AWS 그래프 따라 그리기 5: 반복하는 부분을 for문으로 만들기

2024. 7. 19. 10:23·대기과학/프로그래밍

- 개요

하나의 axes에 그림을 여러 개 그리면 같은 코드를 여러 번 반복할 수밖에 없습니다.

저는 6개의 변수를 그리기 때문에 6번의 비슷한 코드가 반복되죠.

이런 부분은 for문으로 만들어야 관리 및 함수화하기 쉽습니다.

 

만약 for문으로 만들지 않는다면?

실수를 1번 했을 때 수정을 6번 해야합니다. (같은 코드가 6번 반복되니까)

또한, 나중에 코드를 재활용할 때도 수정을 6번 해야합니다.

그리고 보통 몇 주, 몇 개월 후에 코드를 재활용하는 경우가 많습니다.

오랜만에 코드를 다시보면 이 코드가 어떤 순서로 동작하는지 기억도 잘 안나는데

코드는 엄청 길기 때문에 어디를 수정해야되는지도 알기 어려워 혼란스러울겁니다.

 

그리고 기상청 ASOS/AWS 따라그리기에 대한 포스트를 더 연재할 것이라 코드를 for문으로 만들어야 제가 다루기 좋습니다. 그럼 지금까지 만든 코드에 for문을 넣어보겠습니다.

 

- spines method의 두가지 형태

spine method를 쓰는 코드라인을 되짚어 보면

ax.spines.right.set_position()과 같은 식으로

spines 뒤에 .left, .right가 있어 y축의 왼쪽인지 오른쪽인지 지정을 해줍니다.

이렇게 .을 붙여서 method로 호출해도 되지만

ax.spines['right'].set_position()처럼 사용해도 됩니다.

즉  ax.spines.right.set_position()와 ax.spines['right'].set_position()는 같습니다.

 

for문에서는 parameter를 담는 변수를 선언하고 이를 전달하는 방식으로 코딩할 것이므로 후자를 쓰는 것이 좋습니다.

 

- for문으로 만든 코드

import matplotlib.pyplot as plt

# 변수의 이상치를 처리하는 작업을 먼저 해야함
df['WS10'][df['WS10'] == -99.9] = np.NaN

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.)

# 그림을 그릴 때 필요한 변수를 담는 매개인자(parameter) 선언
# 강수 > 온도 > 현지기압 > 습도 > 풍속 > 풍향 순
varnames = ['RN-60m', 'TA', 'PS', 'HM', 'WS10', 'WD10']
colors = [color_RN60, color_TA, color_PS, color_HM, color_WS, color_WD]
ymins = [0, 16, 999, 0, 0, 90] # y최소값
ymaxs = [40, 36, 1019, 100, 20, 90+360] # y최댓값
dys = [4, 2, 2, 10, 2, 90] # y간격
# True는 왼쪽 y축, False는 오른쪽 y축
direction = [True, True, False, False, True, True]
# True면 right, False면 left
direction_str = ['left' if i == True else 'right' for i in direction]
# direction_str과 방향을 반대로
direction_str_reverse = ['right' if i == True else 'left' for i in direction]
# y축 위치 설정
spine_set_positions = [70, 0, 0, 35, 25, 50]

fig = plt.figure(figsize=(13,5))
for i, varname in enumerate(varnames):
    if varname == 'RN-60m':
        ax_base = fig.add_subplot()
        ax = ax_base
        x = range(len(df[varname]))
        dx = x[1] - x[0]
        ax.bar(x, df['RE']*40, color=color_RE, width=dx)
        ax.bar(x, df[varname], color=colors[i], width=dx)
        ax.bar(x, df['RN-15m'], color=color_RN15, width=dx)

    else:
        if varname == 'WD10':
            df.loc[df[varname] < 90, varname] += 360
            ax = ax_base.twinx()
            ax.scatter(x, df[varname], color=colors[i], s=4)

        else:
            ax = ax_base.twinx()
            ax.plot(x, df[varname], color=colors[i], lw=1)
            
    ymin, ymax, dy = ymins[i], ymaxs[i], dys[i]
    ax.set_ylim(ymin, ymax)
    ax.set_yticks(range(ymin, ymax+1, dy))
    
    # set_yticks를 먼저 선언 안하면 set_yticklabels 선언시 오류가 남
    if varname == 'WD10':
        ax.set_yticklabels(['E', 'S', 'W', 'N', 'E']) 
    
    ax.spines[direction_str[i]].set_position(('outward', spine_set_positions[i]))
    ax.spines[direction_str_reverse[i]].set_visible(False)

    ax.yaxis.set_ticks_position(direction_str[i])
    ax.yaxis.set_label_position(direction_str[i])
    
    ax.tick_params(axis='y', which='both', length=0)
    ax.tick_params(axis='y', labelcolor=colors[i])
    if varname == 'TA' or varname == 'PS':
        ax.spines[direction_str[i]].set_color('gray')
        ax.spines[direction_str[i]].set_linewidth(2)
    else:
        ax.spines[direction_str[i]].set_color(colors[i])
        ax.spines[direction_str[i]].set_linewidth(2)

 

이번에 작성한 코드로 그린 그림

솔직히 그냥 이전에 있던 코드를 for문으로 바꾼 것뿐이라 딱히 설명할 것이 더 없네요.

 

참고로 이번 연재에서는 딱히 자동화를 다룰 생각은 없습니다만

아래의 작업을 하시면 그림 그리는 일을 자동화 할 수 있습니다.

 

1. 그림 그리는 부분을 함수 혹은 클래스로 변환하되 parameter값을 입력값으로 받음

2. 다양한 parameter값을 저장하는 문서 작성 (보통 configuration 파일이라 부름)

3. configuration 파일을 수정할 수 있는 코드 작성(보통 shell 파일로 작성함)

 

위의 작업을 하면 3개의 코드가 나올텐데 하나의 코드에서 위의 세 작업을 수행해도 큰 상관은 없습니다.

다만 이러면 코드가 길어져서 유지, 보수가 어렵습니다.

 

다음 포스트에서는 y축 위에 변수 이름, y축 아래에 변수의 단위를 추가해보겠습니다.

'대기과학 > 프로그래밍' 카테고리의 다른 글

[Matplotlib] 기상청 ASOS/AWS 그래프 따라 그리기 7: x축 라벨 적기  (0) 2024.07.25
[Matplotlib] 기상청 ASOS/AWS 그래프 따라 그리기 6: y축 제목, 단위 적기  (2) 2024.07.23
[Matplotlib] 기상청 ASOS/AWS 그래프 따라 그리기 4: y축, 축의 라벨 색 바꾸기  (0) 2024.07.18
[Matplotlib] 기상청 ASOS/AWS 그래프 따라 그리기 3: 선과 음영 그리기  (1) 2024.07.12
[Matplotlib] 기상청 ASOS/AWS 그래프 따라 그리기 2: 왼쪽에 y축 여러 개 그리기  (0) 2024.07.11
'대기과학/프로그래밍' 카테고리의 다른 글
  • [Matplotlib] 기상청 ASOS/AWS 그래프 따라 그리기 7: x축 라벨 적기
  • [Matplotlib] 기상청 ASOS/AWS 그래프 따라 그리기 6: y축 제목, 단위 적기
  • [Matplotlib] 기상청 ASOS/AWS 그래프 따라 그리기 4: y축, 축의 라벨 색 바꾸기
  • [Matplotlib] 기상청 ASOS/AWS 그래프 따라 그리기 3: 선과 음영 그리기
레까
레까
  • 레까
    데이터 조아
    레까
  • 전체
    오늘
    어제
    • 전체 (86)
      • 대기과학 (45)
        • 프로그래밍 (42)
        • 개념 (2)
        • 칼럼 (1)
      • 여러가지 데이터 (5)
        • 프로그래밍 & 분석 (5)
      • 프로그래밍 (15)
        • 파이썬 (8)
        • 시각화 (6)
        • 유용 (1)
      • 프로젝트 (17)
        • 기계학습 기반 서울 기온 예측 (9)
        • 사과게임 매크로 만들기 (4)
        • 버스 한 번으로 특정 지역에 갈 수 있는 지역 찾.. (4)
      • 데이터리안 SQL 공부 (3)
      • 주제별 링크 모음 (1)
      • 백업 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
레까
[Matplotlib] 기상청 ASOS/AWS 그래프 따라 그리기 5: 반복하는 부분을 for문으로 만들기
상단으로

티스토리툴바