IDL에서 날짜 기반의 데이터를 플롯(Plot)의 형태로 표출하는 방법에 관해서는 예전에 관련 게시물들(링크 1, 링크 2, 링크 3)을 통하여 소개했던 적이 있습니다. 이 게시물들에서는 주로 날짜 기반의 포맷 코드를 활용하는 방식으로 처리를 하였으며 이러한 포맷 코드의 사용 방법에 관해서도 관련 게시물들(링크1, 링크 2)을 통하여 따로 소개한 바 있습니다. 실제로 앞서 언급한 관련 게시물들에서는 PLOT 함수의 XTICKFORMAT 속성에 대하여 예를 들면 다음과 같은 방식으로 날짜 기반의 포맷 코드를 부여한 바 있습니다.
XTICKFORMAT='(C(CMoA, " ", CDI, " ", CHI2.2, ":", CMI2.2))'
이러한 방식으로 처리하면 플롯의 X축의 눈금값들이 일정한 포맷의 날짜 형식을 띄게 됩니다. 그런데 이와 같은 처리 방식에 있어서 또 다른 대안이 있는데 바로 LABEL_DATE 함수를 활용하는 방법입니다. 사실 LABEL_DATE 함수는 앞서 언급한 날짜 기반의 포맷 코드를 사용하는 방식과 유사한 측면도 있지만 엄연히 다른 방식이며 그 사용 방식도 약간 독특합니다. 어쨌든 IDL에서 날짜 기반의 데이터를 표출하는데 있어서 잘 알아두면 편리한 기능이기 때문에 이번 기회에 관련 예제와 함께 소개해보도록 하겠습니다. 일단 예제로 사용할 데이터가 수록된 파일은 아래에 첨부하였습니다.
이 파일은 .sav 파일이기 때문에 다운로드한 후 IDL에서는 RESTORE 명령을 사용하여 읽으면 됩니다. 따라서 아래와 같은 내용으로 시작을 해봅시다.
RESTORE, 'data_date_202409.sav'
이렇게 파일을 읽으면 IDL에서는 tjs 및 spd라는 배열들을 인식하게 됩니다. 이 배열들에 관한 정보를 확인하여 출력해보는 과정 및 실제 출력 내용은 다음과 같습니다.
HELP, tjs, spd
PRINT, MIN(spd), MAX(spd)
TJS DOUBLE = Array[319]
SPD FLOAT = Array[319]
285.295 530.289
참고로 이 데이터는 약 15일의 기간 동안의 태양풍(Solar Wind)의 속도값들로 구성된 배열인 spd 그리고 해당 날짜값들이 줄리안 날짜(Julian Date) 단위로 수록된 배열인 tjs로 구성되어 있습니다. 그리고 각 배열은 319개의 값들로 구성되어 있습니다. 그러면 이제는 그래픽창을 띄우고 플롯을 표출하기 위하여 WINDOW 및 PLOT 함수를 사용하고자 합니다. 다만 이 과정에 앞서서 LABEL_DATE 함수를 먼저 사용해야 합니다. 즉 본격적인 표출에 앞서서 LABEL_DATE 함수를 사용하여 축 눈금 문자들의 형식을 정의하는 것이 먼저 필요하다는 것을 유의해야 합니다. 그래서 여기서는 이 과정을 다음과 같이 처리하기로 합니다.
dummy = LABEL_DATE(DATE_FORMAT='%M %D %H:%I')
일단 LABEL_DATE 함수에서 날짜 표기 형식을 지정하는 방식은 위와 같습니다. 물론 위의 내용의 구체적인 의미를 살펴보는 것이 필요할텐데요. 일단 위와 같이 LABEL_DATE 함수의 DATE_FORMAT 키워드에 부여된 문자열을 통해서 날짜 표기 형식을 정의하게 됩니다. 그리고 위에서 DATE_FORMAT 키워드에 부여된 내용인 '%M %D %H:%I'는 LABEL_DATE 함수 내에서만 사용할 수 있는 형태의 날짜 포맷 코드라고 보면 됩니다. 여기서 사용된 항목들의 각각의 의미는 다음과 같습니다.
%M : Month Name 즉 각 월의 이름 (Jan, Feb, Mar 등)
%D : Day of Month 즉 일수를 두자리 숫자로 나타냄
%H : Hours 즉 시를 두자리 숫자로 나타냄
%I : Minutes 즉 분을 두자리 숫자로 나타냄
이러한 내용은 IDL 도움말의 LABEL_DATE 함수에 관한 섹션을 찾아보면 구체적으로 확인할 수 있습니다. 일단 이와 같이 날짜 표기 형식을 정의해놓고 바로 이어서 PLOT 함수에서 사용하면 각 눈금에 대한 날짜가 이러한 형식에 근거하여 표기될 것입니다. 그러면 이제 X축이 날짜이고 Y축이 데이터값인 플롯을 표출하는 과정을 다음과 같이 처리해봅시다.
tj1 = JULDAY(6, 1, 2024, 0, 0, 0)
tj2 = JULDAY(6, 16, 2024, 0, 0, 0)
win = WINDOW(DIMENSIONS=[600, 500], /NO_TOOLBAR)
p = PLOT(tjs, spd, YRANGE=[200, 600], COLOR='tomato', $
XTICKUNITS='day', XTICKFORMAT='label_date', $
XTICKINTERVAL=3, XMINOR=2, XRANGE=[tj1, tj2], $
XTITLE='Date', YTITLE='Speed (km/s)', $
MARGIN=0.1, FONT_SIZE=10, /CURRENT)
여기서 사용된 예제 데이터는 2024년 6월 1일 0시 0분부터 6월 16일 0시 0분까지 정확히 15일의 기간을 커버합니다. 그래서 XTICKINTERVAL 속성을 통하여 큰 눈금(major tick)의 간격이 3일이 되도록 하였고, XMINOR 속성을 통하여 작은 눈금(minor tick)의 갯수가 2개가 되도록 즉 작은 눈금 구간들이 3개가 되도록 하였습니다. 그리고 가장 중요한 부분은 바로 XTICKFORMAT 속성에 대하여 'label_date'라는 문자열을 부여한 것인데, 앞서 LABEL_DATE 함수로 정의했던 날짜 표기 형식이 X축 눈금 문자들의 표기에 적용되도록 하기 위함입니다. 그리고 X축의 큰 눈금의 값들이 모두 일(day) 단위가 되어야 하기 때문에 XTICKUNITS 속성을 'day'로 설정하는 것도 필요합니다. 그리고 X축의 범위가 정확히 6월 1일 0시 0분부터 6월 16일 0시 0분이 되도록 하기 위하여 XRANGE 속성에 대하여 정확한 날짜값이 반영되도록 한 것도 유의해야 합니다. 아무래도 날짜 기반의 플롯을 정확하게 표출하려다보니 이것저것 신경써야 할 부분들이 많습니다. 어쨌든 이러한 과정에 의하여 표출된 플롯의 모습은 다음과 같습니다.
일단 이 그림에서 X축에 주목해보면 앞서 우리가 의도하고 설정했던 특성들은 모두 반영된 것이 보입니다. 특히 X축의 큰 눈금별로 표기된 문자열을 보면 'Jun 04 00:00'과 같은 형식인데, 앞서 우리가 LABEL_DATE 함수의 DATE_FORMAT 키워드로 정의한 '%M %D %H:%I'라는 형식이 그대로 반영된 것입니다. 즉 월, 일, 시, 분의 표기 방식뿐 아니라 각 요소 사이의 공백 및 시와 분 사이의 : 기호까지 모두 반영되었음을 주목하면 됩니다. 실제로 LABEL_DATE 함수에서 사용 가능한 포맷의 종류는 매우 다양하므로 여기서 다 소개하기는 어렵습니다. 따라서 자세한 내용은 IDL 도움말의 LABEL_DATE 함수 섹션을 참조하시기 바랍니다.
다만 여기서 조금만 더 신경을 써본다면 X축의 큰 눈금마다 표기된 문자열이 다소 길다보니 가로 방향으로 문자들이 너무 빽빽하다는 느낌이 듭니다. 따라서 각 문자열에 대하여 줄바꿈을 해서 가로 방향으로 좀 여유가 생기도록 하는 것이 좋을 것 같습니다. 이러한 경우에는 줄바꿈 역할을 하는 !C를 포맷 코드 내에서 사용하면 됩니다. 즉 앞서 LABEL_DATE 함수가 사용되었던 내용만 다음과 같이 변경해봅시다.
dummy = LABEL_DATE(DATE_FORMAT='%M %D!C%H:%I')
이러한 변경 사항만 반영하여 그림을 다시 표출해보면 그 모습은 다음과 같습니다.
이와 같이 월일 다음 시분이 줄을 바꿔서 표기된 것을 볼 수 있습니다. 만약에 연도(year)까지도 함께 표기하고 싶다면 대략 다음과 같이 LABEL_DATE 함수의 내용을 바꿔보면 될 것 같습니다.
dummy = LABEL_DATE(DATE_FORMAT='%Y!C%M %D!C%H:%I')
즉 이와 같이 연도에 해당되는 %Y라는 항목을 추가하면서 연도 바로 뒤에서는 줄바꿈을 하도록 처리하는 것입니다. 다만 이렇게 할 경우 X축 눈금 문자열이 세로 방향으로 길어지기 때문에 플롯 자체의 하단 여백이 좀 더 필요합니다. 따라서 PLOT 함수에서도 여백을 다음과 같이 재조정하는 것이 바람직합니다.
p = PLOT(tjs, spd, YRANGE=[200, 600], COLOR='tomato', $
XTICKUNITS='day', XTICKFORMAT='label_date', $
XTICKINTERVAL=3, XMINOR=2, XRANGE=[tj1, tj2], $
XTITLE='Date', YTITLE='Speed (km/s)', $
MARGIN=[0.1, 0.15, 0.1, 0.1], FONT_SIZE=10, /CURRENT)
이러한 변경 사항들을 반영하여 그림을 다시 표출해보면 결과는 다음과 같습니다.
이와 같이 LABEL_DATE 함수를 사용하여 축 눈금의 문자열을 날짜 기반으로 표기하는 방법은 NG(New Graphics) 체계 뿐 아니라 DG(Direct Graphics) 체계에서도 사용이 가능합니다. 위와 동일한 그림을 DG 체계에서 표출하는 과정은 대략 다음과 같습니다.
tj1 = JULDAY(6, 1, 2024, 0, 0, 0)
tj2 = JULDAY(6, 16, 2024, 0, 0, 0)
dummy = LABEL_DATE(DATE_FORMAT='%Y!C%M %D!C%H:%I')
DEVICE, DECOMPOSED=1
WINDOW, XSIZE=600, YSIZE=500
PLOT, tjs, spd, YRANGE=[200, 600], COLOR='000000'x, BACKGROUND='FFFFFF'x, $
XTICKUNITS='day', XTICKFORMAT='label_date', $
XTICKINTERVAL=3, XMINOR=2, XRANGE=[tj1, tj2], $
XTITLE='Date', YTITLE='Speed (km/s)', $
XMARGIN=[7, 5], YMARGIN=[5, 3]
OPLOT, tjs, spd, COLOR='4763FF'x
코드 내용에 관한 자세한 설명은 생략합니다. 표출된 결과 그림만 보면 다음과 같습니다.
그리고 이와 같이 LABEL_DATE 함수를 사용하여 축 눈금의 문자열이 날짜 형식으로 표기되도록 하는 방법은 제가 예전에 이 블로그를 통하여 소개했던 날짜 기반의 포맷 코드를 사용하는 방법과 유사한 측면이 있습니다. 따라서 LABEL_DATE 함수를 사용하는 대신 이러한 방법으로 처리해도 동일한 결과를 얻을 수 있습니다. 즉 앞서 PLOT 함수가 사용되었던 내용에서 XTICKFORMAT 속성에 'label_date' 대신 날짜 기반 포맷 코드를 사용해도 됩니다. 그러면 PLOT 함수가 사용된 내용을 다음과 같이 수정해봅시다.
p = PLOT(tjs, spd, YRANGE=[200, 600], COLOR='tomato', $
XTICKFORMAT='(C(CYI, "!C", CMoA, " ", CDI2.2, "!C", CHI2.2, ":", CMI2.2))', $
XTICKINTERVAL=3, XMINOR=2, XRANGE=[tj1, tj2], $
XTITLE='Date', YTITLE='Speed (km/s)', $
MARGIN=[0.1, 0.15, 0.1, 0.1], FONT_SIZE=10, /CURRENT)
이러한 변경 사항을 반영하여 다시 실행해보면 앞서 우리가 얻었던 그림들과 동일한 결과를 얻을 수 있습니다.
결론적으로 보면 축의 눈금 문자를 날짜 기반으로 표기하는데 있어서는 오늘 소개한 LABEL_DATE 함수를 사용하는 방법으로 처리해도 되고 제가 예전에 소개했던 날짜 기반 포맷 코드를 사용하는 방법으로 처리해도 됩니다. 사실 두 방법 사이에 엄청난 차이가 있는 것은 아니기 때문에 그냥 유저의 취향에 따라 편한 방법을 선택하여 사용하면 된다 정도로 요약을 해볼 수 있겠습니다.
'IDL > Programming' 카테고리의 다른 글
IDL 8.9에서 추가된 상수 정의 기능 (1) | 2023.06.29 |
---|---|
IDL 8.9의 Literal Strings 문법 (0) | 2023.06.28 |
음수 범위를 로그 스케일(Log Scale)로 표시하기 (0) | 2023.04.25 |
WHILE 및 REPEAT 구문의 이해 (0) | 2023.02.10 |
주프로그램과 부프로그램의 구성 및 운용 방식 (0) | 2022.04.01 |