2010-12-09 10 views
6

Wenn Sie Text in MATLAB-Abbildungen programmgesteuert unter Verwendung einfügen, finde ich häufig, dass sich die Textblöcke überlappen und sie unlesbar machen. Ich habe mich gefragt, ob es eine automatische Möglichkeit gibt, die Textblöcke so zu verschieben, dass sie sich nicht überlappen. Zum Beispiel, wenn ich 3 Etiketten mit der Ausrichtung von oben links an den Punkten (0,0), (0,01,0) und (0,02,0) hinzugefügt hätte, würde ich wollen, dass sie sich neu positionieren:Vermeiden Sie Textüberlappung in MATLAB-Abbildungen

während zur Zeit sie wie folgt aussehen:

. . . 
la~~~~~~l3 

wo die squiggles aufgrund der Überlappung nicht lesbar sind.

Wenn es noch keinen Weg gibt, dies zu tun, könnte ich meinen eigenen Algorithmus/Heuristik für die Aufgabe rollen, aber gibt es eine Möglichkeit, eine Figur (oder die gcf Handle) für die Begrenzungsrahmen aller vorhandenen Textfelder abzufragen drauf? Also kann ich das jedes Mal anrufen, wenn ich ein Label platzieren will?

Danke!

Antwort

5

Sie müssen es nicht selbst tun. Ein Werkzeug, das Textplatzierung behandelt wurde hier diskutiert http://blogs.mathworks.com/pick/2009/01/02/automatic-text-placement/

Der direkte Link zu den Dateiaustausch ist http://www.mathworks.com/matlabcentral/fileexchange/11466

Auch wenn Sie diese wäre ein guter Anfang, um Roll-your-own wollen.

HTH Darren

+0

Das sieht gut aus! Ich suche nach einer Möglichkeit, den Text in der Nähe eines bestimmten Punktes zu platzieren, also ist es keine fertige Lösung, aber es ist in der Tat ein großartiger Ausgangspunkt. Ich werde warten, um zu sehen, ob jemand anderes eine vielseitige Lösung vor der Annahme weiß, aber danke! – btown

6

Hier ist eine Lösung kam ich mit ... scheint gut zu funktionieren.

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

Das ist großartig! Und funktioniert immer noch in 15b. Nur Ärger ist, dass einige Etiketten außerhalb der Achsen enden, aber es funktioniert gut. Danke für das Teilen. –

Verwandte Themen