2010-12-09 241 views
6

當使用text(x,y,'label')以編程方式將文本插入到MATLAB數字中時,我經常發現文本塊重疊,使得它們不可讀。我想知道是否有任何自動的方式來抵消文本塊,所以他們不會重疊。例如,如果我在點(0,0),(0.01,0)和(0.02,0)添加了左上對齊的3個標籤,我希望它們自己重新定位,例如:在MATLAB數字中避免文本重疊

. . . 
label1 
    label2 
    label3 

而目前它們看起來像:

. . . 
la~~~~~~l3 

其中波浪線是不可讀由於重疊。

如果還沒有辦法做到這一點,我可以推出我自己的算法/啓發式任務,但有沒有辦法查詢所有現有文本框邊界框的數字(或gcf句柄)在上面?那麼每次我想放置標籤時都可以打電話給我?

謝謝!

回答

5

你不必自己動手。在這裏討論了處理文本放置的工具 http://blogs.mathworks.com/pick/2009/01/02/automatic-text-placement/

直接鏈接到文件交換 http://www.mathworks.com/matlabcentral/fileexchange/11466

即使你想滾你自己,這將是一個良好的開端。

H個 達倫

+0

這看起來不錯!我正在尋找一種將文本放置在特定點附近的方法,因此它不是一個開箱即用的解決方案,但它確實是一個開始的好地方。在接受之前,我會等待其他人是否知道更多功能的解決方案,但謝謝! – btown 2010-12-09 15:40:27

6

這是我想出了一個解決方案...似乎工作確定。

function h = textfit(x,y,txt,varargin) 
% textfit(x,y,txt,varargin) 
% 
% Mike Lawrence 2011 

ythresh = 0.4; % maximal allowable overlap (includes cell padding accounted for in "extent" property) 
xthresh = 0.1; 

n = length(x); 
if ~iscell(txt), txt={txt}; end 
if length(y)~=n || length(txt)~=n, error('length mismatch between x,y,txt'); end 

h = text(x,y,txt,varargin{:}); 

yl=ylim; ytot=diff(yl); 
xl=xlim; xtot=diff(xl); 

maxtries = 100; 
for t=1:maxtries 
    ext = nan(n,4); 
    for i=1:n, ext(i,:) = get(h(i),'extent'); end 
    xstart=ext(:,1); xsz=ext(:,3); xend=xstart+xsz; 
    ystart=ext(:,2); ysz=ext(:,4); yend=ystart+ysz; 
    overlapx = zeros(n,n); 
    overlapy = zeros(n,n); 
    for i1=1:n-1, for i2=i1+1:n 
    if xstart(i1)<=xend(i2)&xstart(i2)<=xend(i1) 
     overlapx(i1,i2)=(min(xend(i2)-xstart(i1),xend(i1)-xstart(i2)))/(min(xsz(i1),xsz(i2))); 
    end 
    if ystart(i1)<=yend(i2)&ystart(i2)<=yend(i1) 
     overlapy(i1,i2)=(min(yend(i2)-ystart(i1),yend(i1)-ystart(i2)))/(min(ysz(i1),ysz(i2))); 
    end 
    end,end 
    overlapmax = max(overlapx,overlapy); 
    ov = (overlapx>xthresh & overlapy>ythresh); 
    [o1 o2] = find(ov); 
    if isempty(o1), break; end 
    [tmp ord] = sort(overlapmax(find(ov))); 
    o1=o1(ord); o2=o2(ord); 
    moved = false(n,1); 
    for i=1:length(o1), i1=o1(i); i2=o2(i); 
    if moved(i1) || moved(i2), continue; end 
    pos1 = get(h(i1),'position'); 
    pos2 = get(h(i2),'position'); 
    oy = overlapy(i1,i2)*min(ysz(i1),ysz(i2)); 
    ox = overlapx(i1,i2)*min(xsz(i1),xsz(i2)); 
    if oy/ytot < ox/xtot % overlapy is easier to fix 
     shift = 0.5*(1-ythresh)*oy; 
     if ystart(i1)<ystart(i2) % i1 above i2 
     pos1(2)=pos1(2)-shift; pos2(2)=pos2(2)+shift; 
     else      % i1 below i2 
     pos1(2)=pos1(2)+shift; pos2(2)=pos2(2)-shift; 
     end 
    else         % overlapx is easier to fix 
     shift = 0.5*(1-xthresh)*ox; 
     if xstart(i1)<xstart(i2) % i1 left of i2 
     pos1(1)=pos1(1)-shift; pos2(1)=pos2(1)+shift; 
     else      % i1 right of i2 
     pos1(1)=pos1(1)+shift; pos2(1)=pos2(1)-shift; 
     end 
    end 
    set(h(i1),'position',pos1); 
    set(h(i2),'position',pos2); 
    moved([i1 i2]) = true; 
    end 
end 

if nargout==0, clear h, end 
+0

這太棒了!仍然在15b工作。 唯一令人煩惱的是,一些標籤最終在軸外,但效果很好。感謝分享。 – 2016-02-27 14:15:04