2013-02-19 83 views
11

Tôi đang vẽ một số dữ liệu với MATLAB và tôi muốn điều chỉnh khoảng cách giữa nhãn trục và chính trục đó. Tuy nhiên, chỉ cần thêm một chút vào thuộc tính "Vị trí" của nhãn làm cho nhãn di chuyển ra khỏi cửa sổ hình. Có một tài sản "margin" hoặc một cái gì đó tương tự?Khoảng cách giữa nhãn trục và trục trong hình MATLAB

enter image description here

Trong hình trên, tôi muốn tăng khoảng cách giữa các con số và nhãn "Time (s)" trong khi tự động mở rộng kích thước con số để các nhãn không di chuyển ngoài giới hạn .

Đây là cách tôi thiết lập hình/trục.

figure; 
set(gca, ... 
    'Box'   , 'off'      , ... 
    'LooseInset' , get(gca, 'TightInset') * 1.5 , ... 
    'TickDir'  , 'in'       , ... 
    'XMinorTick' , 'off'      , ... 
    'YMinorTick' , 'off'      , ... 
    'TickLength' , [.02 .02]     , ... 
    'LineWidth' , 1       , ... 
    'XGrid'  , 'off'      , ... 
    'YGrid'  , 'off'      , ... 
    'FontSize' , 18       ); 

Trả lời

8

Tôi đã viết một hàm nên làm chính xác những gì bạn muốn. Nó giữ các trục tại cùng kích thước chính xác và vị trí, nó di chuyển x nhãn xuống và làm tăng kích thước hình phải đủ lớn để hiển thị các nhãn:

function moveLabel(ax,offset,hFig,hAxes) 
    % get figure position 
    posFig = get(hFig,'Position'); 

    % get axes position in pixels 
    set(hAxes,'Units','pixels') 
    posAx = get(hAxes,'Position'); 

    % get label position in pixels 
    if ax=='x' 
     set(get(hAxes,'XLabel'),'Units','pixels') 
     posLabel = get(get(hAxes,'XLabel'),'Position'); 
    else 
     set(get(hAxes,'YLabel'),'Units','pixels') 
     posLabel = get(get(hAxes,'YLabel'),'Position'); 
    end 

    % resize figure 
    if ax=='x' 
     posFigNew = posFig + [0 -offset 0 offset]; 
    else 
     posFigNew = posFig + [-offset 0 offset 0]; 
    end 
    set(hFig,'Position',posFigNew) 

    % move axes 
    if ax=='x' 
     set(hAxes,'Position',posAx+[0 offset 0 0]) 
    else 
     set(hAxes,'Position',posAx+[offset 0 0 0]) 
    end 

    % move label 
    if ax=='x' 
     set(get(hAxes,'XLabel'),'Position',posLabel+[0 -offset 0]) 
    else 
     set(get(hAxes,'YLabel'),'Position',posLabel+[-offset 0 0]) 
    end 

    % set units back to 'normalized' and 'data' 
    set(hAxes,'Units','normalized') 
    if ax=='x' 
     set(get(hAxes,'XLabel'),'Units','data') 
    else 
     set(get(hAxes,'YLabel'),'Units','data') 
    end 
end 

Trong trường hợp này offset phải là tuyệt đối bù đắp trong pixel. Nếu bạn muốn bù đắp tương đối, tôi nghĩ rằng chức năng này có thể dễ dàng được viết lại. hFig là tay cầm hình và hAxes các trục xử lý.

EDIT: tạo hình bằng cách sử dụng hFig = figure; và các trục theo hAxes = axes; (sau đó thiết lập các trục như bạn đã làm trong câu hỏi: set(hAxes,...)) trước khi gọi hàm.

EDIT2: thêm các dòng trong đó 'Units' của hAxesXLabel được đổi lại thành 'chuẩn hóa' và 'dữ liệu' tương ứng. Bằng cách đó, con số vẫn theo cách bạn muốn sau khi thay đổi kích thước.

EDIT3: đã sửa đổi chức năng hoạt động cho cả nhãn X và Y. Mục nhập bổ sung ax phải là 'x' hoặc 'y'.

+0

Có sự khác biệt đáng chú ý nào khi giải quyết trục y? Tôi cho rằng bản thân cốt truyện bằng cách nào đó cần phải được di chuyển trong trường hợp đó, đúng không? – Niko

+0

Tôi nghĩ rằng mã này được chuyển đổi khá dễ dàng để hoạt động trên trục y. Tôi đang ở trong xe buýt ngay bây giờ, vì vậy không thể làm điều đó ngay bây giờ, nhưng tôi sẽ xem xét nó sau tối nay (trong vòng một vài giờ) – ThijsW

+0

Vì một số lý do, phương pháp này không thành công, ví dụ: 50 pixel bù đắp trên trục x.Trong thiết lập của tôi, nhãn sau đó được cắt làm đôi. Tuy nhiên, trong phạm vi mong muốn của một vài điểm ảnh chức năng này hoạt động như một nét duyên dáng, vì vậy cảm ơn bạn rất nhiều! – Niko

8

Bạn có thể thực hiện việc này bằng cách điều chỉnh vị trí của trục xlabel. Tôi cũng khuyên bạn nên sử dụng các đơn vị "chuẩn hóa" để vị trí của bạn không phụ thuộc vào phạm vi dữ liệu. Dưới đây là ví dụ:

figure 
plot(rand(1,10)) 

set(gca, 'Units', 'Normalized'); 
pos = get(gca, 'Position'); 
offset = 0.1; 
set(gca, ... 
    'Box'   , 'off'      , ... 
    'LooseInset' , get(gca, 'TightInset') * 1.5 , ... 
    'TickDir'  , 'in'       , ... 
    'XMinorTick' , 'off'      , ... 
    'YMinorTick' , 'off'      , ... 
    'TickLength' , [.02 .02]     , ... 
    'LineWidth' , 1       , ... 
    'XGrid'  , 'off'      , ... 
    'YGrid'  , 'off'      , ... 
    'FontSize' , 18       , ... 
    'Position' , pos + [0, offset, 0, -offset]); 

h = xlabel('Time (s)'); 
set(h, 'Units', 'Normalized'); 
pos = get(h, 'Position'); 
set(h, 'Position', pos + [0, -offset, 0]); 
+0

Điều này có vẻ là một cách tiếp cận tốt, cảm ơn. Tuy nhiên, nếu tôi đặt 'offset = 0,01;', nhãn được đặt trên đường viền của hình và do đó cắt giảm một nửa. – Niko

+0

@Niko Đúng vậy. Bạn sẽ phải chơi xung quanh để có được một giá trị tốt cho bù đắp. Bạn cũng có thể muốn một độ lệch khác nhau cho trục và xlabel. – shoelzer

+1

4 dòng cuối cùng từ đây là tất cả những gì tôi cần để điều chỉnh vị trí nhãn. –

4

Tôi biết điều này đã được trả lời và tất cả, nhưng điều này là (chừng mực nào đó) một cách đơn giản hơn:

relative_offset = 1.5; 
close all; 
figure(99);clf 
plot(rand(1,10)) 
xlabel('The x-axis') 
xh = get(gca,'XLabel'); % Handle of the x label 
pause(0.2) 
set(xh, 'Units', 'Normalized') 
pause(0.2) 
pos = get(xh, 'Position'); 
set(xh, 'Position',pos.*[1,relative_offset,1]) 

Tôi đã bao gồm các lệnh tạm dừng, kể từ khi hệ thống của tôi sẽ nhận được trước bản thân ở một số kỳ lạ cách khác.

/Niels

Các vấn đề liên quan