11/06/2017

[MATLAB] 데이터량이 부족할 시 보간법(interpolation)을 이용해 근사한 그래프 그리기



  데이터량이 적다면 전체적인 경향을 보기 힘들뿐 아니라 그래프로 나타내었을 때 예쁘게 보이지 않는다.  아래 그래프는 PF(Parallel Flow) 열교환기에서 냉매의 열역학적 건도(thermo-dynamic quality)를 해석하고 나타낸 그래프이다. 경향을 자세히 보기위해 많은 데이터를 취득하여 매트랩의 mesh 그래프를 그렸으나 빈 공간이 많아 희미해 보인다.

빈공간을 없애주는 간단한 방법은 mesh 그래프 대신에 surf 그래프를 그리는 것이다. 면들의 집합으로 그려지므로 아래와 같이 나타난다. 이 그래프는 선명해 보이기는 하나 경계선이 많이 있어 추가적인 정보를 기입하기 곤란하다.

  위 그래프는 데이터량이 충분히 있어 괜찮지만 데이터량이 부족하면 보기도 좋지않고 성의없어 보인다. 그럴 때 적용할 수 있는 매트랩의 griddata 함수가 있다. 이 함수를 활용하면 데이터의 빈공간을 선형보간법으로 채워넣어 근사한 그래프를 그릴 수 있다. (가로(열) 데이터를 먼저 선형보간법 처리하고 세로(행) 데이터를 선형보간법 처리하는 것으로 짐작된다.)

  위 그래프를 예로 설명하면 'M_x_ref' 로 명명된 68 x 20 사이즈의 행렬이 있고 이 행렬만 가지고 mesh나 surf 그래프를 그리면 위와 같이 나타난다. 이 때 행과 열번호로 x축 y축이 자동으로 만들어진다. 참고로 0 - 20 으로 나타낸 축은 각 튜브를 나눈 segment 번호이고 0 - 80 으로 나타낸 축은 튜브의 번호를 나타낸다. 이 행렬(M_x_ref)에 보간법을 적용하여 그래프를 그리기 위한 코드는 아래와 같다.

---------------------------------------------------------------------------------------
X_seg = 1:20;
Y_tube = 1:68;

X_num = 1:0.1:20;
Y_num = 1:0.1:68;

[X_mtrx, Y_mtrx] = meshgrid(X_num, Y_num);

Z_mtrx = griddata(X_seg, Y_tube, M_x_ref, X_mtrx, Y_mtrx);

mesh(X_mtrx, Y_mtrx, Z_mtrx)


set(gcf, 'Color', 'w')
colorbar
-------------------------------------------------------------------------------------
- 변수들 설명 - 
  X_seg : 원래 행렬(M_x_ref)의 열번호 벡터 (size 1 x 20)
  Y_tube : 원래 행렬(M_x_ref)의 행번호 벡터 (size 1 x 68)

  X_num : 보간법으로 증가시킬 열번호 벡터 정의 (size 1 x 191)
  Y_num : 보간법으로 증가시킬 행번호 벡터 정의 (size 1 x 671)

  X_mtrx : 3차원 그래프를 그리기 위한 x값 행렬 (size 671 x 191)
  Y_mtrx : 3차원 그래프를 그리기 위한 y값 행렬 (size 671 x 191)

  M_x_ref : 원래 행렬  (size 68 x 20)
  Z_mtrx : 보간법(or 내삽법)으로 데이터 갯수가 증가된 행렬 (size 671 x 191)


  3차원 그래프를 그리기 위해서는 x축, y축, z축 정보를 가지는 2차원 행렬들이 각각 필요하다. 보간법을 적용할 데이터 간격, 갯수 등의 정보를 'X_num', 'Y_num' 에 기입하였다. 이 x축, y축 벡터들을 meshgrid 함수에 입력하면 3차원 그래프를 그리기 위한 x축, y축 행렬 'X_mtrx', 'Y_mtrx' 를 매트랩에서 만들어 준다. 그리고 위 코드 처럼 griddata 함수를 적용하면 보간법이 적용되어 조밀해진(?) 행렬 'Z_mtrx' 가 만들어 진다. 이 3개의 행렬들로 mesh 그래프를 그렸고 바탕색은 휜색, 칼라바를 넣기위해 몇 줄 추가하였다. 코드를 실행하면 아래와 같이 깔끔하고 근사한 그래프가 나타난다.




- 위 코드를 테스트하고 싶으면 아래 코드를 앞에 추가하여 임의의 행렬을 생성 후 실행
    M_x_ref = rand(68,20);      % (20, 68) 이 아님에 주의 (Y, X)

- X_seg, Y_tube 등은 정수일 필요 없음.
    ex) X_seg = 0.5 : 0.1 : 4.0;     , X_num = 0.5 : 0.01 : 4.0





댓글 1개:

  1. 'M_x_ref' 의 값을 예로 정했으면 좋았을거 같습니다. 테스트를 해볼수가 없네요.

    답글삭제