지난 첫 회 게시물에서는 Delete, Erase, Close 메서드들에 관하여 알아보았습니다. 오늘 두번째 게시물에서는 하나만 좀 집중적으로 언급하고자 합니다. 바로 SetData라는 메서드입니다. 이 메서드 역시 웬만한 그래픽 함수들에 거의 다 지원되는데, 그 역할은 그래픽을 구현하는데 사용되는 데이터(data)만 변경하는 것입니다.
좀 더 구체적으로 풀어서 얘기해보면, 그래픽 개체에서 다른 부가적인 요소들말고 순수한 데이터 부분만 변경한다는 뜻인데요. 플롯(Plot)의 경우는 XY축과 같은 부가적인 요소들을 제외한 실제 데이터에 해당되는 플롯(plot)선에 해당되는 데이터, 즉 x와 y가 그 대상이 됩니다. 이미지(Image), 등위선(Contour), 면(Surface) 등의 경우는 대상이 되는 2차원 데이터 자체가 됩니다. 이러한 데이터부분만 다른 데이터로 대체하는 역할을 수행하는 메서드가 바로 SetData입니다. 예제를 통해서 살펴보기로 합시다. 먼저 다음과 같이 x, y 데이터를 정의하고 PLOT 함수로 그림을 그려보았는데요.
win = WINDOW(DIMENSIONS=[600, 500])
x = FINDGEN(361)
y1 = SIN(x*!DTOR)
pl = PLOT(x, y1, XRANGE=[0, 360], YRANGE=[-1, 1], XTICKINTERVAL=90, $
COLOR='crimson', THICK=2, /CURRENT)
여기서 x는 0~360도의 각도값들이고 y1은 그에 대응되는 Sine값들입니다. 이제 이 상태에서 플롯의 골격은 그대로 둔 채 y 데이터만Cosine값들로 바꿔보겠습니다. 먼저 다음과 같이 Cosine값들로 구성된 y2를 생성하고, 플롯 개체인 pl에 대하여 SetData 메서드를 사용하여 데이터 부분만 대체합니다. 그러면 결과는 다음과 같습니다.
y2 = COS(x*!DTOR)
pl.SetData, y2
실제로 이 과정을 프로그램으로 돌려보면 플롯의 골격인 XY축 부분은 전혀 바뀌지 않고 데이터에 해당되는 붉은 선만 변경되는 것을확인할 수 있습니다. 또 주목할 부분은 처음에 PLOT 함수를 사용하여 플롯 개체를 구현해놓은 상태에서, 다시 한번 PLOT 함수를 사용하는 방식이 아니라 내부 데이터만 슬쩍 바꾸는 방식이라는 점입니다. 그렇기 때문에 PLOT 함수는 처음 한번만 사용할 뿐, 그 이후 데이터를 변경하여 표출해야 할 경우에는 그냥 SetData 메서드로 새로운 데이터로 갱신하면 됩니다. 이번에는 Cosine 곡선의 높이를 절반으로 줄인 형태로 변경하는 작업을 다음과 같이 해보았습니다. 역시 기본 요령은 위와 같습니다.
y2 = COS(x*!DTOR)*0.5
pl.SetData, y2
그런데 혹시 예전의 그래픽 체계인 DG(Direct Graphics)의 PLOT 프로시저에 익숙하셨던 유저들이 보시기에는 이 방식이 어떤 중요성을 갖는지 잘 와닿지 않을 수도 있습니다. 사실 위와 같은 작업을 DG 체계에서 할 경우에는 PLOT 프로시저를 매번 반복해서 사용해야 합니다. 그래야만 갱신된 데이터로 그림을 그릴 수 있기 때문입니다. 이건 DG 체계에서는 당연한 방법입니다. 그렇다면, NG 체계에서의 PLOT 함수를 DG 체계의 PLOT 프로시저처럼 사용해도 될까요? 즉 데이터가 변경될 때마다 PLOT 함수를 재차 사용하는 것도 괜찮을까요? 정답을 말씀드리면, "허용은 되지만 권장되지는 않는다"입니다. 그 이유는 NG 체계에서는 그래픽 개체 하나하나가 메모리를 차지하기 때문입니다. 따라서 예를 들어 PLOT 함수를 10회 반복하여 사용하게 되면 그 10회분의 메모리를 점유하게 됩니다. 반대로 DG 체계의 PLOT 프로시저로 그려진 플롯은 메모리를 점유한 개체가 되지 않습니다. 그냥 화면상에 뿌려지고 기억 자체가 사라져버립니다. 그렇기 때문에 PLOT 프로시저를 10회 반복하여 사용하더라도 메모리가 더 점유되거나 하지 않습니다. 그리고 어차피 DG 체계에서는 어떤 그림이든간에 데이터가 변경되는 것을 반영하려면 처음부터 다시 그려야 합니다. 물론 메모리 부담이 전혀 없으므로 여러번 반복에 있어 아무 문제가 없습니다. 하지만 NG에서는 그렇지 않기 때문에 SetData와 같은 메서드를 잘 활용할 필요가 있습니다.
이러한 특성 때문에 NG 체계에서의 그래픽 함수의 사용에 있어서 유의가 약간 필요합니다. 특히 비슷한 성격의 데이터를 여러 회차에 걸쳐 순차적으로 변경하여 나타내야 할 경우라면 더욱 그렇습니다. 그런 이유로 좀 귀찮게 느껴질 수도 있겠지만, NG 체계 그래픽의 다른 장점들을 위해서는 고려해야 할 부분이라고 생각해두시면 좋겠습니다. 대신 이 SetData 메서드를 잘 활용하면 좀 더 재미있는 코딩이 가능해지는데요. 예를 들면, 다음과 같이 반복구문의 블록내에서 SetData 메서드를 활용하는 것입니다. 이 프로그램을 한번 실행해보시기 바랍니다. 뭔가 재미있는 현상이 벌어질 것입니다.
win = WINDOW(DIMENSIONS=[600, 500])
x = FINDGEN(361)
y1 = COS(x*!DTOR)
pl = PLOT(x, y1, XRANGE=[0, 360], YRANGE=[-1, 1], XTICKINTERVAL=90, $
COLOR='crimson', THICK=2, /CURRENT)
FOR j = 600, 0, -1 DO BEGIN
amplitude = FLOAT(j)/300-1
y2 = COS(x*!DTOR)*amplitude
pl.SetData, y2
ENDFOR
구동을 해보면 아마도 Cosine 함수에 +1부터 -1까지의 값들을 단계적으로 곱하여 그 패턴이 변하는 과정이 순차적으로 나타날 것입니다. 이 과정에서는 총 601회에 걸쳐서 플롯의 데이터가 변경됩니다. 그런데 이러한 과정을 정말 매번 PLOT 함수가 반복 실행되는방식으로 진행하면, 반복회차가 진행될수록 점점 실행속도가 느려지게 될 것입니다. 불필요하게 메모리 점유량이 점점 누적될 것이기때문입니다. 하지만 이와 같이 SetData 메서드를 잘 활용하면 많은 회차의 작업을 진행하면서도 메모리의 낭비를 최소화하고 작업 효율을 높일 수 있습니다.
이 SetData 메서드의 구체적 사용 방식은 그래픽 개체의 종류별로 약간씩 다릅니다. 여기서는 PLOT 함수로 구현된 개체를 예로 들었지만, 그 외에 CONTOUR, IMAGE, SURFACE, POLYGON 등 각 그래픽 함수별로 약간씩 다른데요. IDL 도움말에서 SetData 메서드에 관한 내용을 보면, 각 그래픽 함수별 사용법들이 잘 나와있으므로 참조해두시면 좋습니다.
제가 이 블로그에서 IDL로 동영상 컨텐츠를 제작하는 예제들을 몇번 소개해드린 적이 있었는데, 모두 NG 체계의 그래픽을 기반으로 한 컨텐츠를 담고 있었습니다. 이러한 동영상을 구성하는 프레임 하나하나를 생성하는데 있어서는 이와 같은 SetData 메서드가 중요한 역할을 했었다는점을 다시 한번 언급드리고 싶습니다. 다음은 앞서 601회에 걸쳐 데이터가 변경되는 과정을 따로 동영상 파일로 만들어본 것입니다. 즐감하시길 바랍니다.
'IDL > New Graphics' 카테고리의 다른 글
에러바(Error Bar)의 표출 (0) | 2015.12.17 |
---|---|
플롯(Plot)을 다중으로 중첩하여 표출하는 방법 (축까지 추가) (0) | 2015.12.14 |
NG 그래픽 함수의 주요 메서드(Method) 사용법 [1] (0) | 2015.11.20 |
IDL로 만든 태양 활동영역(Active Region) 동영상 (0) | 2015.11.13 |
NG 체계에서 사용 가능한 컬러 이름 목록 보기 (2015. 07 버전) (0) | 2015.07.27 |