벡터 범례 문의

게시판 IDL Q&A 벡터 범례 문의

이 게시글은 4개 답변과 3명 참여가 있으며 마지막으로  ChoiYoun에 의해 2 월, 4 주 전에 업데이트 됐습니다.

  • 글쓴이
  • #5465 답변

    ChoiYoun
    회원

    안녕하세요. 벡터의 범례를 그릴 때 벡터의 크기 및 위치가 계속 변경되어서 글 남깁니다. 아래는 간단한 예시코드입니다.

    for i = 0, 9 do begin
    uu = 10. * RANDOMN(seed, 10, 10)
    vv = 10. * RANDOMN(seed, 10, 10)
    v = VECTOR(uu, vv, MIN_VALUE = 0, MAX_VALUE = 60, BUFFER = 1)
    v_legend = LEGEND(TARGET = v, SAMPLE_MAGNITUDE = 10, UNITS=’$m s^{-1}$’)
    v.Save, STRING(STRING(i), FORMAT = ‘(I0)’) + ‘.png’
    endfor

    추측하기에 최솟값과 최댓값의 변화 때문에 범례가 움직이는 듯하여 LEGEND에 POSITION 키워드를 추가하고, 벡터에 임의로 동일한 최솟값과 최댓값을 넣어보았습니다. 그러나 여전히 제 명령을 무시하고 범례가 조금씩 움직입니다. 불행 중 다행으로 길이는 비슷해보이긴 합니다만, 이것도 범례가 계속 움직여서 정확히 확인하기 어렵습니다.

    for i = 0, 9 do begin
    uu = 10. * RANDOMN(seed, 10, 10)
    vv = 10. * RANDOMN(seed, 10, 10)

    vv[0] = 40
    uu[0] = 40
    uu[-1] = 0.01
    vv[-1] = 0.01

    v = VECTOR(uu, vv, MIN_VALUE = 0, MAX_VALUE = 60, BUFFER = 1)
    v_legend = LEGEND(TARGET = v, SAMPLE_MAGNITUDE = 10, UNITS=’$m s^{-1}$’, POSITION = [0.95, 0.975])
    v.Save, STRING(STRING(i), FORMAT = ‘(I0)’) + ‘_1.png’
    endfor

    이렇다보니, 범례가 문제인지 벡터가 문제인지 헷갈리기 시작했습니다. VECTOR에 MIN_VALUE와 MAX_VALUE를 키워드를 사용하면 다른 자료(다른 시간 등)를 그리더라도 벡터의 길이는 동일할 줄 알았는데, 그렇지 않을지도 모른다는 의심이 들기 시작했습니다.

    조언 부탁드립니다.

  • #5466 답변

    mwkim
    회원

    안녕하세요.

    우선 올려주신 부분에서 벡터 크기가 그릴때마다 달라진다는 부분과 관련하여 아래와 같은 내용을 찾을 수 있었습니다.

    IDL 도움말 – VECTOR에서

    ————————

    Tip: The purpose of the VECTOR function is to draw a vector field or wind field at a series of (X, Y) locations. The units of the vector or wind field are arbitrary, and are not related to the units for the X and Y coordinates. The ARROW function (with the DATA keyword) may be used to draw arrows that are directly related to the X and Y coordinates.

    Note: The units for the U and V components are arbitrary, and are not related to the units of the X and Y coordinates. The VECTOR function will compute a default length scale and head size based upon the overall number of vectors and the average magnitude of the vectors. The LENGTH_SCALE and HEAD_SCALE properties may be used to change the default size.

    ————————

    대략 해석하기로는 VECTOR 함수는 실제 X, Y 축과는 무관하게 그려지며
    함수에서 표출하는 벡터의 수와 크기를 기준으로 스케일이 자동으로 정해진다고 보여집니다.

    실제 올려주신 예제에서도 표출하면 축과 실제 그려지는 벡터 스케일이 다른 것을 확인할 수 있습니다.
    (또한 같은 원리로 입력 U, V 값의 스케일을 조정하더라도 그려지는 그림은 동일합니다.)

    다만 추정되기로는 두번째 예제와 같이 벡터의 스케일은 U, V의 최대 크기(Maximum magnitude)에 의해서 정해지는 것이 아닌가 합니다(추정입니다. 도움말에서는 어떻게 정의되는지 명시되지 않았습니다.)

    따라서 두번째 예제는 최대값을 고정했기 때문에 벡터는 동일한 스케일로 그려졌다고 보여집니다.

    그리고 두번째 예제에서 범례(레전드)가 계속 움직이는 현상은 아래와 같이 동일한 창에 연속으로 표출하면 동일하게 표출되는 것을 확인했습니다.

    ————————

    w = WINDOW()
    for i = 0, 9 do begin
    uu = 10. * RANDOMN(seed, 10, 10)
    vv = 10. * RANDOMN(seed, 10, 10)

    vv[0] = 40
    uu[0] = 40

    v = VECTOR(uu, vv, MIN_VALUE = 0, MAX_VALUE = 60)
    v_legend = LEGEND(TARGET = v, SAMPLE_MAGNITUDE = 10, UNITS=’$m s^{-1}$’, POSITION = [0.95, 0.975])
    WAIT,3 & w.Erase ; 이 부분을 주석처리하면 벡터 그림이 겹쳐지는 것에 반해 레전드는 동일한 것을 확인할 수 있습니다.
    endfor

    ————————

  • #5467 답변

    ChoiYoun
    회원

    답변 감사합니다. 말씀하신대로 WINDOW 함수를 사용해 동일한 그래픽 창에 벡터와 범례를 겹쳐 그렸을 때, LEGEND가 동일하게 나오는 것처럼 보였습니다. 그런데 동일한 프로그램을 열번 정도 실행하면 두어번 이상 범례가 어긋나는 경우가 발생합니다.

    그래서 원인을 찾고자 아래와 같이 벡터의 최댓값, 최솟값, 평균값을 출력하였으나, 어긋나는 경우에 특별한 값을 보이진 않았습니다(spd 변수의 최댓값과 최솟값은 동일).

    w = WINDOW()
    for i = 0, 9 do begin
    uu = 10. * RANDOMN(seed, 10, 10)
    vv = 10. * RANDOMN(seed, 10, 10)
    uu[0] = 40 &uu[-1] = 0.01
    vv[0] = 40 &vv[-1] = 0.01
    spd = SQRT(uu ^ 2. + vv ^ 2.)
    v = VECTOR(uu, vv, MIN_VALUE = 0, MAX_VALUE = 60, /CURRENT)
    v_legend = LEGEND(TARGET = v, SAMPLE_MAGNITUDE = 10, UNITS=’$m s^{-1}$’, POSITION = [0.95, 0.975])
    print, MIN(spd), MAX(spd), MEAN(spd), v_legend.position
    wait, 3
    endfor

    • 이 답변은  ChoiYoun에 의해 3 월 전에 수정됐습니다.
  • #5469 답변

    Sangwoo
    회원

    VECTOR 함수에서 MIN_VALUE, MAX_VALUE 속성의 역할은 벡터를 표시할지 말지를 결정하는 경계값을 지정하는 역할입니다. 올리신 예제코드의 내용에 맞춰서 얘기한다면, 길이가 0보다 작거나 60보다 큰 벡터는 표시를 하지 않고 0~60의 범위에 속하는 벡터들만 표시를 하겠다는 의미입니다. 아마도 이 속성의 역할을 벡터 길이의 스케일을 규정하는 역할로 생각하셨던 것으로 보이는데, 제가 보기에도 속성의 이름 자체가 약간 혼란스러운 부분이 있는 것도 사실입니다.

    어쨌든 제가 보기에는, 어떤 데이터를 갖고 벡터 표출을 하더라도 화살표 길이의 스케일을 완전히 고정시키는 것을 목표로 하시는 것 같습니다. 사실 VECTOR 함수에서 화살표 길이의 스케일은 기본적으로는 IDL이 알아서 조정을 하도록 되어 있습니다. 아마도 제 짐작으로는 u, v 데이터로부터 길이(Magnitude)의 최대값을 산출한 후 그림상에서 특정 화살표가 지나치게 길게 표시되지 않도록 어느 정도 길이 조정을 거쳐서 표출하는 것 같습니다. 이렇게 IDL이 알아서 길이 조정을 하다보니, 데이터가 변할 때마다 화살표 길이의 스케일도 매번 변할 수 밖에 없습니다. 처음 질문에서 언급하셨던 현상은 VECTOR 함수의 디폴트 행동으로는 자연스러운 모습입니다. 아마 반복을 해보시면 레전드에서 나타나는 화살표의 길이(10m/s에 대응되는)가 MAX(spd)가 클 때 짧고 MAX(spd)가 작을 때 긴 것을 보실 수 있을 겁니다.

    하지만 어떤 데이터가 들어오든 간에 10m/s에 대응되는 화살표의 길이가 항상 고정되도록 하려면 별도의 처리가 필요합니다. 이 때 사용 가능한 속성이 LENGTH_SCALE이란 속성입니다. 이 속성의 디폴트값은 1입니다. 만약 2나 3으로 설정하면 정상 길이보다 2배나 3배 긴 화살표들이 표시됩니다. 물론 이 속성의 값을 2나 3으로 설정하는 정도의 방법으로는 길이 스케일 고정은 안됩니다. 이를 위해서는 스케일 값을 매 데이터마다 계산해서 투입해줘야 합니다. 이를 위한 내용을 첫 질문에서 올리셨던 예제 코드에 추가하면 다음과 같습니다.

    win = WINDOW(/NO_TOOLBAR)
    FOR i = 0, 9 DO BEGIN
    uu = 10*RANDOMN(seed, 10, 10)
    vv = 10*RANDOMN(seed, 10, 10)
    spd = SQRT(uu^2+vv^2)
    spd_str = ‘Max Speed : ‘+STRING(MAX(spd), FORMAT='(F0.2)’)
    scl = MAX(spd)/60.*3
    v = VECTOR(uu, vv, MIN_VALUE=0, MAX_VALUE=60, TITLE=spd_str, $
    LENGTH_SCALE=scl, HEAD_SIZE=scl/2, /CURRENT)
    v_legend = LEGEND(TARGET=v, SAMPLE_MAGNITUDE=10, UNITS=’$m s^{-1}$’)
    PRINT, MIN(spd), MAX(spd), MEAN(spd), v_legend.position
    WAIT, 1
    IF i NE 9 THEN v.Erase
    ENDFOR

    여기서 핵심이 되는 부분은 scl이란 변수의 계산인데, MAX(spd)를 기준값은 60으로 나눠준 다음 적당한 배율(여기서는 3)을 더 곱한 것입니다. 이 scl을 LENGTH_SCALE 속성에 부여하면 길이가 항상 고정됩니다. 그리고 HEAD_SIZE 속성은 화살표 머리 부분의 길이인데, 원래는 이 길이도 데이터에 따라 변하게 되어 있지만 여기서는 scl 변수값을 활용해서 적당히 고정되도록 처리하였습니다. 이 내용을 실행해보면 데이터가 매번 변하더라도 10(m/s)에 해당되는 화살표 길이는 항상 고정되는 것을 볼 수 있을 것입니다.

  • #5470 답변

    ChoiYoun
    회원

    감사합니다. 덕분에 많은 문제가 해결되었습니다.

    LEGEND의 POSITION이 계속 움직이는 문제는 POSITION 키워드를 나중에 주는 것으로 해결하였습니다.

    v_legend = LEGEND(TARGET=v, SAMPLE_MAGNITUDE=10, UNITS=’$m s^{-1}$’)
    v_legend.POSITION = [0.95, 0.975]

    • 이 답변은  ChoiYoun에 의해 2 월, 4 주 전에 수정됐습니다.
'벡터 범례 문의'에 답변달기
글쓴이 정보: