2012-06-22 5 views
3

간단한 레이블을 만드는 서브 플로트를 제공하고 싶습니다. 불행히도 나는 추한 행동을하고 있습니다.matlab 그림의 서브 플로트 레이블

figure; 
h1 = axes('OuterPosition', [0,0,.5 1]); 
set(h1,'LooseInset',get(h1,'TightInset')); 
h2 = axes('OuterPosition', [.5,0,.5 1]); 
set(h2,'LooseInset',get(h2,'TightInset')); 

axes(h1); 
plot([0 1], [4 5]); 
set_label1('A'); 

axes(h2); 
plot([0 1], [4 5]); 
set_label1('B'); 

내가 얻을 그림은 다음과 같습니다 : 여기

function h = set_label1(label) 
tlh = get(gca, 'Title'); 
if strcmp(get(tlh, 'String'), '') 
    title(' '); 
end 
ylh = get(gca, 'YLabel'); 
if strcmp(get(ylh, 'String'), '') 
    ylabel(' '); 
end 

ylp = get(ylh, 'Position'); 
x = ylp(1); 

tlp = get(tlh, 'Position'); 
y = tlp(2); 

h = text('String', label, ... 
     'HorizontalAlignment', 'right',... 
     'VerticalAlignment', 'Baseline', ... 
     'FontUnits', 'pixels', ... 
     'FontSize', 16, ... 
     'FontWeight', 'bold', ... 
     'FontName', 'Arial', ... 
     'Position', [x y 0]); 
end 

는 간단한 테스트 실행 : 다음과 같은 기능을 고려하면 그림 크기를 조정하면

enter image description here

라벨은하지 않습니다 더 이상 올바른 위치에 있어야합니다. 괜찮 았어, 나는 그것을 기대했다. (그들이 속한 곳으로 되돌려 놓는 방법을 안다면 나에게 매우 행복해 할 것이라고 말한다.)

제가 직면 한 문제는 '데이터'단위로 라벨의 위치를 ​​지정하고 싶지 않다는 것입니다. 대신 정규화 된 단위를 사용하고 싶습니다. 그래서 나는 수정 된 형태의 함수를 사용했다. 이제 우리는이를 사용하자 :

function h = set_label2(label) 
tlh = get(gca, 'Title'); 
if strcmp(get(tlh, 'String'), '') 
    title(' '); 
end 
ylh = get(gca, 'YLabel'); 
if strcmp(get(ylh, 'String'), '') 
    ylabel(' '); 
end 

oldUnits = replace_prop(ylh, 'Units', 'normalized'); 
ylp = get(ylh, 'Position'); 
x = ylp(1); 
set(ylh, 'Units', oldUnits); 

oldUnits = replace_prop(tlh, 'Units', 'normalized'); 
tlp = get(tlh, 'Position'); 
y = tlp(2); 
set(ylh, 'Units', oldUnits); 

h = text('String', label, ... 
     'HorizontalAlignment', 'right',... 
     'VerticalAlignment', 'Baseline', ... 
     'FontUnits', 'pixels', ... 
     'FontSize', 16, ... 
     'FontWeight', 'bold', ... 
     'FontName', 'Arial', ... 
     'Units', 'normalized',... 
     'Position', [x y 0]); 
end 

function oldvalue = replace_prop(handle, propName, newvalue) 
oldvalue = get(handle, propName); 
set(handle, propName, newvalue); 
end 

을 동일한 테스트를 실행 :

figure; 
h1 = axes('OuterPosition', [0,0,.5 1]); 
set(h1,'LooseInset',get(h1,'TightInset')); 
h2 = axes('OuterPosition', [.5,0,.5 1]); 
set(h2,'LooseInset',get(h2,'TightInset')); 

axes(h1); 
plot([0 1], [4 5]); 
set_label2('A'); 

axes(h2); 
plot([0 1], [4 5]); 
set_label2('B'); 

우리는 이전과 똑같은 사진을 얻을 수 있습니다. 유일한 문제는 우리가 나쁜 일을 크기를 조정할 때 발생하는 것입니다 :

enter image description here

레이블이 올바른 위치에 실제로. 그러나 내가 사용한 'LooseInset''TightInset' 속성은 축이 레이블이없는 것처럼 작동합니다. 이 문제가 수정 되었습니까? 내가하는 모든 일은 정규화 된 단위의 제목과 ylabel의 위치를 ​​데이터 단위와 반대되게하는 것입니다. 그리고 이것은 이것을 엉망으로 만드는 것 같습니다.

정규화 된 단위로 가져와야하는 이유는 3D 플롯을 얻을 때 제목과 zlabel에 대해 레이블을 배치 할 수 있기 때문입니다. 모든

+0

테스트 코드에서'LooseInset'을 변경하는 코드를 제거하더라도 여전히'set_label2'와 동일한 동작을합니다. – jmlopez

+0

그런데'LooseInset'은 [문서화되지 않은] (http://undocumentedmatlab.com/blog/axes-looseinset-property/) 속성 – Amro

답변

1

첫째, 나는 데이터 단위를 계속 사용 지금 영리 왼쪽 상단 모서리에있는 텍스트 :

의 위치를 ​​제목/Y-라벨을 사용하는 대신에 표준화 된 단위를 사용하여 당신의 생각을 좋아하고 제목 또는 y- 라벨이 위치를 변경할 때마다 이벤트 리스너를 만들고 새 값을 사용하여 만든 텍스트를 다시 조정합니다.

그래서 당신 set_label1 함수의 끝에 다음을 추가합니다 (우리는 X를 설정하거나 y 좌표할지 여부를 제어 할 마지막 인수 idx 사용)

addlistener(ylh, 'Position', 'PostSet', @(o,e) posChanged(o,e,h,1)) 
addlistener(tlh, 'Position', 'PostSet', @(o,e) posChanged(o,e,h,2)) 

을 여기에 두 가지 경우에 사용되는 콜백 함수입니다 :

function posChanged(src,evt,hTxt,idx) 
    posLabel = evt.NewValue;   %# new position of either title/y-label 
    posText = get(hTxt, 'Position'); %# current text position 
    posText(idx) = posLabel(idx);  %# update x or y position (based on idx) 
    set(hTxt, 'Position',posText)  %# adjust the text position 
end 
+0

입니다. 리스너를 추가하는 방법을 알려 주셔서 감사합니다. 결국 정규화 된 단위를 사용하여 작동하도록 결정했습니다. 그러나 이번에는 축의 '위치'와 '외부 위치'를 얻습니다. 이 정보를 사용하여 왼쪽 상단 모서리를 기준으로 레이블의 위치를 ​​지정할 수 있습니다. 이렇게하면 3D에서도 작동합니다. – jmlopez

+0

@jmlopez : 후손을 위해 새 코드를 게시하는 것도 고려해야합니다. – Amro

+0

할 것이다, 나는 단지 이벤트 리스너와 관련된 한 가지 문제를 해결하려고하고있다. – jmlopez

2

내가 후회하기로 결정한 버전은 후손을위한 것입니다. 그것은 내가 기대하는 바를 수행하지만, 지금 나는 해결할 방법을 모른다는 문제가 있습니다. 좋아, 먼저 좋은 소식은 axes_label이라는 기능입니다.

function c = axes_label(varargin) 

if isa(varargin{1}, 'char') 
    axesHandle = gca; 
else 
    axesHandle = get(varargin{1}{1}, 'Parent'); 
end 

if strcmp(get(get(axesHandle, 'Title'), 'String'), '') 
    title(axesHandle, ' '); 
end 
if strcmp(get(get(axesHandle, 'YLabel'), 'String'), '') 
    ylabel(axesHandle, ' '); 
end 
if strcmp(get(get(axesHandle, 'ZLabel'), 'String'), '') 
    zlabel(axesHandle, ' '); 
end 

if isa(varargin{1}, 'char')  
    label = varargin{1}; 
    if nargin >=2 
     dx = varargin{2}; 
     if nargin >= 3 
      dy = varargin{3}; 
     else 
      dy = 0; 
     end 
    else 
     dx = 3; 
     dy = 3; 
    end 
    h = text('String', label, ... 
     'HorizontalAlignment', 'left',... 
     'VerticalAlignment', 'top', ... 
     'FontUnits', 'pixels', ... 
     'FontSize', 16, ... 
     'FontWeight', 'bold', ... 
     'FontName', 'Arial', ... 
     'Units', 'normalized'); 
    el = addlistener(axesHandle, 'Position', 'PostSet', @(o, e) posChanged(o, e, h, dx, dy)); 
    c = {h, el}; 
else 
    h = varargin{1}{1}; 
    delete(varargin{1}{2}); 
    if nargin >= 2  
     if isa(varargin{2}, 'char') 
      set(h, 'String', varargin{2}); 
      if nargin >=3 
       dx = varargin{3}; 
       dy = varargin{4}; 
      else 
       dx = 3; 
       dy = 3; 
      end 
     else 
      dx = varargin{2}; 
      dy = varargin{3}; 
     end 
    else 
     error('Needs more arguments. Type help axes_label'); 
    end 
    el = addlistener(axesHandle, 'Position', 'PostSet', @(o, e) posChanged(o, e, h, dx, dy)); 
    c = {h, el}; 
end 
posChanged(0, 0, h, dx, dy); 
end 

function posChanged(~, ~, h, dx, dy) 
    axh = get(h, 'Parent'); 
    p = get(axh, 'Position'); 
    o = get(axh, 'OuterPosition'); 
    xp = (o(1)-p(1))/p(3); 
    yp = (o(2)-p(2)+o(4))/p(4); 
    set(h, 'Units', get(axh, 'Units'),'Position', [xp yp]); 
    set(h, 'Units', 'pixels'); 
    p = get(h, 'Position'); 
    set(h, 'Position', [p(1)+dx, p(2)+5-dy]); 
    set(h, 'Units', 'normalized'); 
end 

그래, 우리는 어떻게 이런 허위 기능을 사용합니까?

% c = axes_label('label') 
%  Places the text object with the string 'label' on the upper-left 
%  corner of the current axes and returns a cell containing the handle 
%  of the text and an event listener. 
% 
% c = axes_label('label', dx, dy) 
%  Places the text object dx pixels from the left side of the axes 
%  and dy pixels from the top. These values are set to 3 by default. 
% 
% c = axes_label(c, ...) 
%  Peforms the operations mentioned above on cell c containing the 
%  handle of the text and the event listener. 
% 
% c = axes_label(c, dx, dy) 
%  Adjusts the current label to the specifed distance from the 
%  upper-left corner of the current axes. 

을 우리가 이전과 동일한 테스트를 수행 할 경우 :

figure; 
h1 = axes('OuterPosition', [0,0,.5 1]); 
set(h1,'LooseInset',get(h1,'TightInset')); 
h2 = axes('OuterPosition', [.5,0,.5 1]); 
set(h2,'LooseInset',get(h2,'TightInset')); 

axes(h1); 
plot([0 1], [4 5]); 
axes_label('A'); 

axes(h2); 
plot([0 1], [4 5]); 
axes_label('B', 250, 250); 

이제 우리는 내가 원하는 것을 얻기 우리는 이러한 사용을 가질 수 있도록 내가 그것을했다. 레이블 'A'는 축의 바깥 쪽 상자의 왼쪽 위 모서리에 설정됩니다. 그리고 B 레이블 왼쪽 상단 구석에서 250 픽셀이되도록 명시 적으로 설정했습니다. 여기 줄거리는 다음과 같습니다

enter image description here

내가이 기능에 대해 좋아하는 내가 저장한다면 세포가에서 반환 된 후 나는 위치를 변경할 수 있습니다 돌려 놓을 것입니다. 예를 들어 label = axes_label('A'); 인 경우 명령 프롬프트에서 label = axes_label(label, 10, 20);을 수행하면 내 레이블 이동이 표시됩니다.

export_fig('testing.png', '-nocrop', '-painters'); 

다음이 내가 얻을 그림입니다 : 내가 이것을 사용하려고하면

지금 직면하고있어 문제는 기능 export_fig

에 ralated된다.

enter image description here

내가 그들을 위치했던 레이블을 인쇄에서 확인 작업을 할 것 export_fig 이벤트 리스너를 추가하기 전에 내가 레이블 B.과 과장 이유입니다. 하지만 어쨌든 지금은 export_fig가 그것이하는 주장을하지 않습니다.

enter image description here

아마이 : 대신에 우리는 이것이 우리가 얻을 다음 옵션 -painters을 제거하면이 화면에

를 나타날 때 주로 재현

그림/축이 이미지를 수출 내가 청취자와 경험이 없기 때문에 코드에 버그가 생겼다. 그래서 누군가가이 행동을 고칠 수 있거나이 코드를 개선 할 수 있다면 자유롭게 해답으로 공유 할 수있다.

관련 문제