2010-12-09 57 views
6

Lors de l'insertion de texte dans les figures MATLAB par programmation en utilisant text(x,y,'label'), je trouve souvent que les blocs de texte se chevauchent, ce qui les rend illisibles. Je me demandais s'il y avait un moyen automatisé de décaler les blocs de texte afin qu'ils ne se chevauchent pas. Par exemple, si j'ai ajouté 3 étiquettes avec l'alignement haut-gauche aux points (0,0), (0,01,0) et (0,02,0), je voudrais les repositionner comme:Éviter le chevauchement de texte dans les figures MATLAB

. . . 
label1 
    label2 
    label3 

alors qu'actuellement ils ressemblent:

. . . 
la~~~~~~l3 

où les gribouillis sont illisibles en raison du chevauchement. S'il n'y a pas moyen de le faire, je pourrais lancer mon propre algorithme/heuristique pour la tâche, mais est-il possible d'interroger une figure (ou la poignée gcf) pour les cadres de délimitation de toutes les zones de texte existantes dessus? Alors je peux appeler ça chaque fois que je veux placer une étiquette?

Merci!

Répondre

5

Vous n'avez pas à le faire vous-même. Un outil qui gère le placement de texte a été discuté ici http://blogs.mathworks.com/pick/2009/01/02/automatic-text-placement/

Le lien direct vers l'échange de fichiers est http://www.mathworks.com/matlabcentral/fileexchange/11466

Même si vous voulez rouler soi-même ce serait un bon endroit pour commencer.

Hth Darren

+0

Cela a l'air génial! Je cherche un moyen de placer le texte à proximité d'un point donné, donc ce n'est pas une solution prête à l'emploi, mais c'est vraiment un bon point de départ. Je vais attendre de voir si quelqu'un d'autre connaît une solution plus polyvalente avant d'accepter, mais merci! – btown

6

Voici une solution que je suis venu avec ... semble fonctionner OK.

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

C'est génial! Et travaille toujours dans 15b. Seul inconvénient est que certaines étiquettes finissent en dehors des axes, mais cela fonctionne bien. Merci d'avoir partagé. –