MATLAB에서 3D plot을 그릴 때 주의할 점이 있다.
MATLAB에서는 결과값이 행렬로 나올 때 plot을 하면
행(row)을 Y축으로 인식하고, 열(column)을 X축으로 인식한다.
그런데 이것은 우리의 직관과 다르다.
예를 들어
$f(x_{1},x_{2}) = (1-x_{1})^2+100(x_{2} - x_{1}^{2})^{2}$라는 함수가 있다고 하자.
내가 $(x_{1},x_{2})$ 값을 넣을 때
당연히 f라는 변수에 (1,1)항목은 $(x_{1}(1),x_{2}(1))$값을 넣는다. 여기서 $x_{1}(1)$은 $x_{1}$후보 중에 첫 번째 값을 넣는다는 뜻이다.
(2,1)항목에는 $(x_{1}(2),x_{2}(1))$ 를 넣는다.
그런데 MATLAB의 변수에서 첫 번째 INDEX는 행을 의미한다.
여기서 혼돈이 온다.
그래프를 그릴 때 첫 번째 인덱스(=행)은 Y축으로 인식하고, 두 번째 인덱스(=열)은 X축으로 인식한다.
그런데 보통 notation 상 값을 넣을 때는 X에 대응되는 곳은 첫 번째 인덱스, Y에 대응되는 곳은 두 번째 인덱스가 된다.
따라서 실제 값과 MATLAB 3D plot 상에 축이 반대로 되는 현상이 발생한다.
그래서 surf와 같은 함수를 쓸 때는 반드시 Z축에 plot할 값을 Transpose해줘야 한다.
아래는 로젠브록 함수를 surf를 이용해서 그리는 것이다.
J = @(x_1,x_2) (1-x_1)^2 + 100*(x_2 - x_1^2)^2 ;
x = -10:0.1:10 ;
[x_1,x_2] = meshgrid(x);
num = length(x) ;
J_eval = zeros(num) ;
for i = 1 : num
for j = 1 : num
J_eval(i,j) = J(x(i),x(j)) ;
end
end
% plot
figure;
s = surf(x_1,x_2,J_eval') ;
s.EdgeColor = 'none';
xlabel('x_1') ;
ylabel('x_2') ;
title('Rosenbrok function') ;
위의 코드를 보면 Z축에 들어가는 J_eval 을 transpose했다
보충설명을 하면, 일반적으로 MATLAB의 help 센터에서 surf를 사용할 때는 다음과 같이 z값을 구해서 하기를 권한다.
J = @(x_1,x_2) (1-x_1)^2 + 100*(x_2 - x_1^2)^2 ;
x = -10:0.1:10 ;
[x_1,x_2] = meshgrid(x);
J_eval = (1-x_1).^2 + 100*(x_2 - x_1.^2).^2 ;
% plot
figure;
s = surf(x_1,x_2,J_eval) ;
s.EdgeColor = 'none';
xlabel('x_1') ;
ylabel('x_2') ;
title('Rosenbrok function') ;
위 코드처럼 계산하면 굳이 transpose를 해줄 필요가 없다.
아래 그림은 help에 있는 예시이다.
위의 meshgrid 코드를 실행해서 x_1을 열어보면
다음처럼 열을 기준으로 값이 바뀌는 것을 확인할 수 있다. x_1은 x축에, x_2는 y축에 들어가는데 x_1이 열 기준으로 -10,-9.9... 바뀌는 것을 보면 x_1, x_2를 가지고 계산하는 것이 더 속편할 수도 있다.
그런데 나의 경우에는 위 코드처럼 surf를 쓰려는 게 아니라 다른 코드에서 데이터를 수집해서 z축 값을 저장한 다음에, surf를 쓰려고 하다보니 축에 혼동이 온 경우라서, 나같은 사람을 위해 글을 작성한다.
'프로그래밍 Programming > 매트랩 MATLAB' 카테고리의 다른 글
[MATLAB] Function handle array 만들기 (0) | 2022.06.14 |
---|---|
[MATLAB] 유용한 디폴트 default 속성 명령어 저장 (0) | 2022.06.05 |
[MATLAB] 사용자 정의 함수 (로컬 함수, 중첩 함수, 익명 함수, 프라이빗 함수) (0) | 2022.05.17 |
[MATLAB] 그래프 제목에 LaTeX를 쓰고 싶을 때 (0) | 2022.05.08 |
[MATLAB] Symbolic 식에서 복잡한 숫자로 된 분수를 소수로 바꾸기 (0) | 2022.04.07 |