지난 회차 게시물에서는 기상청 ASOS 장비의 기상요소 관측자료를 기상자료 개방포털 웹페이지에서 CSV 파일로 수신한 다음 이 파일을 IDL에서 읽고 처리하여 개별 기상요소를 시계열 플롯의 형태로 가시화하는 과정을 관련 예제와 함께 소개한 바 있습니다. 여기서는 특정한 하나의 지점에 대하여 자료의 전체 기간에 걸친 기온의 시계열 플롯을 얻었는데, 오늘은 특정한 시각에 대한 모든 지점들의 기온 값들을 지도상에 표출하는 방식으로 작업을 진행해보겠습니다. 자료 파일은 지난 회차에서 사용했던 CSV 파일을 그대로 사용합니다.
또한 이 파일을 수신하고 READCOL 명령으로 읽는 과정까지는 지난 회차 게시물에서 소개했던 내용과 거의 동일합니다. 초반부의 과정은 다음과 같습니다.
file = 'OBS_ASOS_TIM_20250108162821.csv'
READCOL, file, stnids, dstrs, temps, temps_qc, $
FORMAT='I,X,A,F,I', DELIMITER=',', /NAN, /PRESERVE_NULL
HELP, stnids, dstrs, temps, temps_qc
이렇게 하면 CSV 파일 내에 수록된 모든 지점번호, 날짜, 기온, 기온 플래그 값들을 담은 배열들인 stnids, dstrs, temps, temps_qc를 얻게 됩니다. HELP에 의하여 출력된 정보를 보면 다음과 같습니다.
STNIDS INT = Array[4753]
DSTRS STRING = Array[4753]
TEMPS FLOAT = Array[4753]
TEMPS_QC INT = Array[4753]
이와 같이 각 배열은 4753개의 값들로 구성됩니다. CSV 파일 내에 수록된 모든 데이터 즉 전체 시간 및 전체 지점들에 대한 데이터를 모두 읽었기 때문입니다. 하지만 후속 작업에서는 대상이 될 하나의 시각에 대한 데이터만 필요하기 때문에 별도의 과정을 거쳐 이러한 데이터만 따로 추출하는 것이 필요합니다. 즉 특정한 시각에 대한 모든 지점들의 기온 값들을 추출해야 하는데, 그 과정은 다음과 같이 처리해봅시다.
dstr = '2025-01-03 01:00'
ww = WHERE(dstrs EQ dstr, count)
stnids = stnids[ww]
temps = temps[ww]
temps_qc = temps_qc[ww]
HELP, stnids, temps, temps_qc
여기서는 먼저 특정한 시각을 2025년 1월 3일 01시(KST)로 정하고 이에 해당되는 문자값을 형식에 맞게 정의하여 변수 dstr에 담았습니다. 그 다음에는 WHERE 함수를 사용하여 시각만 특정하여 추출하면 됩니다. 따라서 원래의 데이터는 모든 지점 및 모든 시각에 걸친 4753개의 값들로 구성되어 있었지만 이러한 추출 과정을 거치면 2025년 1월 3일 01시에 대한 모든 지점들의 값들만 추출될 것입니다. HELP에 의하여 출력된 정보를 보면 총 97개의 값들이 추출된 것으로 확인되는데 이는 ASOS 지점들의 총 갯수와 동일합니다.
STNIDS INT = Array[97]
TEMPS FLOAT = Array[97]
TEMPS_QC INT = Array[97]
그리고 temps_qc의 경우는 지난 회차 게시물에서도 이미 언급하였듯이 기온값들에 대한 품질 체크 고유 번호들로 구성된 배열입니다. 일단 여기서는 결측이 아닌 유의미한 값들만 추려해는 과정이 필요합니다. 이러한 과정이 필요한 이유는 나중에 지도상에 지점별 기온 값들을 표시할 때 혹시라도 결측인 지점 즉 기온 값이 없는 지점이 있을 경우에는 이를 제외하기 위해서입니다. 이 과정은 다음과 같이 WHERE 함수에서 품질 번호가 9가 아닌 경우 즉 결측이 아닌 경우들에 대한 배열 인덱스 정보를 얻는 방식으로 처리합니다.
wgood = WHERE(temps_qc NE 9, cgood)
그러면 이러한 정보를 바탕으로 기온값 배열인 temps에 대하여 인덱싱을 해줌으로써 결측이 아닌 정상적인 관측값들로만 구성된 새로운 배열을 얻을 수 있습니다.
temps_good = temps[wgood]
그 다음에는 ASOS 지점 메타 자료로부터 각 지점들의 경위도 좌표값 배열들을 가져오는 것이 필요합니다. 이를 위해서는 첫 회차 게시물에서 얻었던 .sav 파일을 불러오면 됩니다.
RESTORE, 'ASOS_stations.sav'
그러면 경도 및 위도 좌표값들로 구성된 배열인 lons, lats를 얻게 되는데, 앞서 얻었던 wgood으로 인덱싱을 하여 새로운 배열을 얻어야 합니다. 앞서 temps_good을 얻었던 과정과 유사합니다.
lons_good = lons[wgood]
lats_good = lats[wgood]
일단 HELP를 사용하여 이 배열들의 정보를 확인해보면 다음과 같습니다.
HELP, temps_good, lons_good, lats_good
TEMPS_GOOD FLOAT = Array[97]
LONS_GOOD FLOAT = Array[97]
LATS_GOOD FLOAT = Array[97]
이 내용을 보면 결측 데이터는 없는 것으로 확인됩니다. 이제 이러한 과정을 거친 temps_good, lons_good, lats_good 배열들을 사용하여 지점별 기온값들을 지도상에 분포도의 형태로 표출하는 것이 가능합니다. 예를 들면 각 지점의 위치에 원형 기호의 형태로 나타내면서 그 색상이 기온의 값에 따라 다르게 보이도록 하는 방법을 생각해볼 수 있습니다. 따라서 이 작업은 먼저 MAP 함수 등 지도 표출 기능 함수들을 이용하여 한반도 지도를 표출하고 그 다음에는 SCATTERPLOT 함수 또는 BUBBLEPLOT 함수를 사용하는 방식으로 진행하면 될 것 같습니다. 먼저 한반도 지도를 표출하는 과정은 첫번째 회차 게시물에서 제시된 방식을 거의 그대로 사용하기로 합니다. 그 과정은 다음과 같습니다.
win = WINDOW(DIMENSIONS=[800, 850], /NO_TOOLBAR)
m = MAP('Geographic', LIMIT=[33, 124, 40, 131], FONT_SIZE=11, $
MARGIN=[0.07, 0.05, 0.07, 0.10], /CURRENT)
mc = MAPCONTINENTS(/HIRES, FILL_COLOR=[240, 240, 240])
m.MapGrid.LINESTYLE = 1
m.MapGrid.LABEL_POSITION = 0
m.MapGrid.HORIZON_LINESTYLE = 0
그 다음에는 기온 값들의 분포를 각 지점별로 그 값에 따라 색상이 다른 기호들로 표시할 차례입니다. 앞서 언급했듯이 이러한 작업을 위해서는 SCATTERPLOT 또는 BUBBLEPLOT 함수를 사용하는 것이 모두 가능하겠지만, 여기서는 BUBBLEPLOT 함수를 사용해보기로 합니다. 이 함수를 사용하는 방법에 관해서는 전에도 관련 게시물들을 통하여 소개한 바 있으므로 그 내용을 참조하여 다음과 같이 처리해봅시다.
sp = BUBBLEPLOT(lons_good, lats_good, $
COLOR=BYTSCL(temps_good, MIN=-10, MAX=10), RGB_TABLE=34, $
BORDER=1, LINECOLOR='black', SIZING=0.25, /OVERPLOT)
여기서 BUBBLEPLOT 함수에 의하여 버블(bubble)의 형태로 표시될 지점들의 경위도 좌표 데이터는 우리가 앞서 얻었던 lons_good, lats_good를 사용하였습니다. 그리고 각 지점별 버블의 색상이 기온 값에 따라 차별화되도록 하기 위하여 temps 배열에 대하여 BYTSCL 함수를 적용하여 -10~+10의 범위에 해당되는 바이트 스케일링 처리를 하고 이를 COLOR 속성에 부여하였습니다. 버블들의 색상은 34번 컬러테이블에 맞춰서 표시되도록 하였고 크기는 0.25로 설정해보았습니다. 그리고 컬러바 및 캡션 문자도 필요할 것이기 때문에, 다음과 같이 COLORBAR 및 TEXT 함수를 사용하여 이들이 그래픽창의 상단의 적절한 위치에 표시되도록 해봅시다.
cb = COLORBAR(TARGET=sp, RANGE=[-10, 10], /BORDER, $
POSITION=[0.2, 0.91, 0.8, 0.94])
tx = TEXT(0.5, 0.96, dstr+', Temperature ('+'$\deg$'+'C)', ALIGNMENT=0.5, $
FONT_SIZE=12, /NORMAL)
이상과 같은 내용을 모두 반영하여 실행해보면 다음과 같은 그림을 얻을 수 있습니다.
그리고 앞서 사용된 BUBBLEPLOT 함수의 내용에 다음과 같이 /SHADED 속성을 추가하여 다시 실행하면 다음과 같은 그림을 얻을 수도 있습니다.
sp = BUBBLEPLOT(lons_good, lats_good, /SHADED, $
COLOR=BYTSCL(temps_good, MIN=-10, MAX=10), RGB_TABLE=34, $
BORDER=1, LINECOLOR='black', SIZING=0.25, /OVERPLOT)
이와 같이 /SHADED 속성을 사용하면 버블들의 색상에 쉐이딩(shading) 효과가 적용됩니다. 즉 각 버블이 마치 3차원적인 공(ball)과 같은 형체이고 주변에 가상의 광원(light source)이 있어서 그 빛을 받으면서 밝은 부분과 어두운 부분이 함께 나타나는 느낌으로 표시가 됩니다. 다만 이렇게 할 경우에는 버블 자체의 색상도 약간 다르게 보이기 때문에 상단의 컬러바의 색상들과의 괴리감이 생길 수 밖에 없다는 점은 감안해야 합니다. 어쨌든 이러한 표출에 있어서 버블들의 크기, 색상 등과 같은 세부적인 특성들은 유저의 취향에 따라 얼마든지 바꿀 수 있겠지만, 대략 위와 같은 표출 방식이 하나의 괜찮은 예제가 될 수 있을 것 같습니다.
이 글이 도움이 되었다면 게시물에 대하여 공감 버튼(하트 모양) 클릭 및 블로그 구독도 해주시면 더 큰 힘이 됩니다. 감사합니다.
'IDL > Programming' 카테고리의 다른 글
기상청 ASOS 자료의 지점별 시계열 표출 (0) | 2025.01.14 |
---|---|
기상청 ASOS 지점 분포 자료 획득 및 표출 (0) | 2025.01.07 |
JSON 데이터의 수신/처리/표출 예제 (0) | 2024.12.23 |
HttpRequest 클래스 소개 (1) | 2024.12.09 |
LABEL_DATE 함수의 활용법 (1) | 2024.09.24 |