본문 바로가기
매트랩(Matlab)/매트랩 강의

[Matlab / 매트랩] 14. 4차(4 dimensional) 데이터 표현하기

by freezkim 2010. 3. 31.
[Matlab / 매트랩] 매트랩 강의 14번째 - 4차 데이터 표현하기

네네 원래는 수치해석쪽으로 가려다가 4차 데이터(?)를 표현하는 방법에 대해 질문이 들어와서 급 방향을 바꿨습니다.
꽤나 쓸모있는 내용이라 강의로 올리려고 해요ㅋ

예전엔 우리가 했던건, 2차원, 3차원 그래프 그리기를 했었는데요.
이번엔 데이터가 x,y로 두개 혹은 x,y,z로 세개일 때가 아닌 x,y,z,V ( v-_- 후훗 ) 요렇게 4개가 있을 때 그래프를 한번 그려보고자 합니다.

그런데 아시다시피 우리가 데이터가 4개일때 4차원 그래프를 그려주면 참 좋겠지만 4차원 그래프를 그릴수가 없잖아요??ㅠㅠ
그래서 어쩔수없이.....3차원 그래프에다가 색깔을 입히는 방식으로 데이터를 표현하는 방법을씁니다.

무슨소리냐면: x,y,z로 3차원 그래프를 그린 다음에, 그 x,y,z좌표에 해당하는 V데이터를 색깔로 나타내는거죠.
이해를 돕기 위해 (....) 예시 그래프를 준비해봤습니다
 

여기서 보시면 x,y,z축에 데이터가 있고 색깔이 뭔가 알록달록하게 새겨져 있는데요. 이 색깔의 데이터가 x,y,z좌표에 해당하는 v의 데이터라고 생각하시면 되겠습니다.


 예를들어 x,y,z가 -1,-1,-1 이라면 위의 그림에서 빨간점에 해당하는 데이터가 되겠지요. 요 지점의 색깔은 대략 매우 빨강이기에 오른쪽의 막대를 보시면 대충 1.7언저리의 값이라는 것을 알 수 있습니다.
 즉, (x,y,z)=(-1,-1,-1) 좌표에 해당하는 v의 데이터는 1.7정도라는걸 아는거죠. 요런식으로 데이터가 4개인 경우에 대한 그래프를 나타낼 수 있답니다.

 데이터가 어떻냐에 따라 다음과 같이 다른 형태의 그래프가 나올 수 있겠죠:)

이거 왠지 좀 맛있게 생겼네-_-^;; 무지개떡 먹고싶다


그럼 본격적으로 한번 그리는 방법을 알아보도록 할게요.
5강과 6강의 3차원 그래프와 3차원 도형 그리기를 해보시고 오시면 이해하는데 도움이 훨씬 잘될거에요ㅋ

이건 설명하기가 거시기하니 사건의 발단이 된 문제의 그래프..를 직접 따라 그리는 걸로 이해를 해봅시다.
그리고 싶은 그래프는 요거에요
  ->> f = (x^2 + y^2 + z^2)^0.5 

예전에 3차원 그래프를 그릴때는 데이터 구조가 밑의 그림과 같았습니다.


여기서 z라는 데이터는 n by m의 행렬의 형태를 가지므로
x,y데이터를 이용해서 z데이터를 만들기 위해 "meshgrid"라는 명령어를 이용해서 x,y를 n by m 행렬로 변환했었습니다.
(지금부터 이게 뭔 외계어 $%$^#$%#^# 이렇다면 5강을 차근차근히 읽어주세요.)

하지만 이번엔 x,y,z에 해당하는 f데이터를 만들어야 되기 때문에 데이터 구조가 이런 그림과 같은 형태로 나타나게 되겠죠.

여기서, 3차원 그래프 그리기에서 z를 만들기 위해 x,y를 n by m의 행렬로 변환했듯이
f데이터를 만들기 위해선 x,y,z를 만들기 위해 x,y,z를 n by m by k 의 행렬(???.......) 로 만들어야 될것입니다.

다행이도 meshgrid가 그 작업을 똑같이 해주기 때문에 그냥 편안하게 써주시면 됩니다ㅋ
먼저 x,y,z 범위를 지정하구요.
x=[-1:0.1:1];
y=[-2:0.1:1];
z=[0:0.1:1];

그다음  meshgrid로 행렬변환을 합니다.
[X,Y,Z]=meshgrid(x,y,z);

자 그럼 대망의 f를 구합니다.
f = (X.^2+Y.^2+Z.^2).^0.5;

요렇게 하면 m by n by k의 형태로 f데이터가 지정된것을 볼수 있습니다.


자 일단 한 고비는 넘었네요.
(사실 한건 범위 지정하고 meshgrid쓴게 단데ㅠㅠ 허허)

이제 요 데이터를 가지고 그래프를 한번 그려봐야겠죠. 하지만 기존의 mesh나 surf따위로 우리가 원하는 그림을 그릴순 없을 겁니다. 요기서 바로바로봐로 6강의 3차원 도형 그리기가 응용되는거죠.

6강에서는 patch라는 명령어를 이용해서, 꼭지점좌표를 입력하고, 꼭지점으로 이뤄진 면의 정보를 입력해서 도형을 그리는 방법을 썼습니다. 이때 각 면마다 색깔을 다르게 지정할 수가 있었더랬죠.

만약에 요 x,y,z데이터를 꼭지점 좌표 + 면의 정보 형태로 변환할 수 있고, f데이터로 면마다 입력해주는 색깔의 데이터를 바꿀 수가 있다면 4차 데이터를 가지고 그래프를 그릴 수 있을겁니다!! 그리고 물논 당연히, 매트랩은 요런 기능을 손쉽게 제공해주지요:) 요태까지 그래와꼬 아패로도 개솤

자 그럼 그래프를 직접 그려보도록 합시다.

1) x,y,z데이터를 꼭지점 좌표 + 면의 정보 형태로 변환하기 
 x,y,z데이터를 patch형태로 쓰기위해 변환하기 위해선 isosurface라는 명령어를 사용합니다. 요 isosurface의 형식은 다음과 같은데요:

 isosurface(x좌표,y좌표,z좌표,f데이터,기준숫자)

 뒤에 이 '기준숫자'값과 같은 'f데이터'에 해당하는 그래프를 그려줍니다.
 뭔소리냐면 f(1,1,1)=1, f(1,2,1)=1, f(1,3,1)=1이라는 데이터가 있고 기준숫자를 1로 잡는다면 (1,1,1) , (1,2,1) , (1,3,1)을 연결해주는 도형을 그려준단 말이죠. 만약에 이 기준숫자가 없다면 도형 자체가 그려질 수가 없게되겠죠.
(생각해보세요 뭔가의 기준이 있어야 그 좌표들을 연결할텐데 그 기준이 없다면 x,y,z는 단순한 범위일 뿐이겠죠.)

자 그래서 기준숫자를 2로 잡고 변환한 결과는 다음과 같습니다.

>> fv=isosurface(X,Y,Z,f,2);



2) patch를 이용해서 그래프 그리기.
>> p=patch(fv); 
 fv는 변환된 데이터라서 그냥 patch로 썼구요. 이러면 결과는 다음과 같은 형상을 보입니다.



 색깔도 거무튀튀(?) 한데다 2차원이니 색도 빨간색으로 바꾸고, 3차원 형상으로 봅시다. set 명령어를 이용하여 면 색깔을 빨간색, 꼭지점 색깔은 없게 만들었습니다.

>> set(p,'FaceColor','red','EdgeColor','none');
>> daspect([1 1 1])
>> view(3); axis tight 


 허허 3차원이긴 3차원인데 3차원이 아닌듯한 3차원이군요.
 명암을 줘서 3차원스럽게 바꿔볼까요?
 
>> camlight left
>> lighting phong


자 이렇게 하면 일단 f=2인 지점에 대한 형상은 나타나게 됩니다.
하지만 우리가 원하는건 요게아니죠ㅠ f가 2일때 데이터 보고 싶은게 아니라 x,y,z에 대해 f의 변화를 보고 싶은것이었습니다.

그런데 그렇다고 이걸 안해버리면, 데이터의 기준이 없어져서 x,y,z에 대해 f의 데이터가 어떠한 패턴을 띄는지 알수가 없잖아요.
그래서 이렇게 f의 데이터를 지정해놓고 그래프를 그린 뒤,
f의 최소값에서 2까지의 데이터 변화 양상을 보거나 혹은 f의 최대값에서 2까지의 데이터 변화 양상을 보는 것으로 해결을 한답니다.

그러면 f의 최소값에서 2까지의 데이터 변화 양상을 볼게요ㅋ

3) x,y,z데이터를 꼭지점 좌표 + 면의 정보 형태로 변환하기, 하지만 f의 변화 양상을 볼 수 있도록!!
이때는 isosurface 대신에 isocaps라는 명령어로 patch형태의 데이터로 변환해 줍니다. 쓰는 형태도 동일해요.

isocaps(x좌표,y좌표,z좌표,f데이터,기준숫자)

하지만 이 경우 차이가 있다면 f데이터가 최대값에서 기준숫자까지의 데이터 변화 정도를 보여주거나 혹은 최소값에서 기준숫자까지의 데이터 변화 정도를 보여주는데!! 벽면에 대해서만 보여 줍니다. 예를들자면 이런식이죠.
 
 
그래서 위에서 사용한 isosurface와 isocaps를 둘다그려야 완전한 하나의 그래프가 완성되는 거죠.
위의 과정에 이어서 isocaps를 사용하면 다음과 같습니다.

>> fv2=isocaps(X,Y,Z,f,2,'below');
(여기서 below는 f의 최소값에서부터 2까지 데이터를 그리기 위해 준 옵션입니다.)


4) patch를 이용하여 isocaps에 대한 그래프 그리기
 2)와 마찬가지로 patch를 쓸 수 있는 데이터가 만들어 졌으니 fv2를 이용해서 그래프를 그려봅시다. 단, 요때는 색깔을 f의 데이터에 변화에 따라 다르게 줄거니 FaceColor옵션을 interp로 지정합니다.

>> p2=patch(fv2, 'FaceColor','interp','EdgeColor','none');
이렇게 하시고 f데이터에 따라 색깔을 rgb로 줄지, 회색으로 줄지, 녹색계열로 줄지 뭔가 결정을 해야겠죠ㅋ 이를 위해 colormap이란 명령어를 사용합니다.
>> colormap('jet');

rgb옵션을 주기 위해 jet를 쎴습니다. (회색의 경우는 gray, 녹색계열은 summer 등입니다. help -> colormap을 보시면 됩니다)
색깔에 따른 데이터 값을 넣기 위해 옆에 막대를 추가합니다
>> colorbar;

요거슨 쪼까 거시기 하죠잉? 처음의 isosurface에 맞춰서 그래프 범위가 설정되어 그렇습니다.
그래서 다시 그래프 범위를 재설정합니다.
>> daspect([1 1 1])
>> view(3); axis tight 


결과적으로 요런 그래프를 얻을수가 있습니다ㅋ

위의 코드는 설명을 위해 isosurface->patch->3D로 표현 -> isocaps->patch -> 3D로 표현.
이 순서였는데, 실제 코드를 칠때는 isosurface,isocaps->patch->3D로 표현. 요렇게 정리해 줄수 있습니다.
따라서 총 정리한 코드는 다음과 같습니다 ::

x=[-1:0.1:1];
y=[-2:0.1:1];
z=[0:0.1:1];
[X,Y,Z]=meshgrid(x,y,z);

f = (X.^2+Y.^2+Z.^2).^0.5;
fv=isosurface(X,Y,Z,f,2);
fv2=isocaps(X,Y,Z,f,2,'below');
p=patch(fv,'FaceColor','red','EdgeColor','none'); 
p2=patch(fv2, 'FaceColor','interp','EdgeColor','none');
colormap('jet');
colorbar;
daspect([1 1 1])
view(3); axis tight 

camlight left
lighting phong

grid on
xlabel('x');ylabel('y');zlabel('z');
title('f = (x^2 + y^2+ z^2)^{0.5}')
isonormals(X,Y,Z,f,p);    %% 표면을 매끌매끌하게 해주는 기능을 가집니다ㅋ


최종 결과네요ㅋ camlight left를 한번 더 쳐주시면 좀더 밝아집니다ㅋ



허허 이제 뭔가 강의가 장난없이 얄짧없군요, 2차원 그래프 그리기만 할때도 쉬웠는 느낌이었는데ㅠㅠㅠㅠㅠㅋㅋ