textfit.m (2345B)
1 function h = textfit(x,y,txt,varargin) 2 % textfit(x,y,txt,varargin) 3 % Mike Lawrence 2011 4 % 5 % Chad 6 % txt needs to be 'cell' 7 % 8 9 ythresh = 0.4; % maximal allowable overlap (includes cell padding accounted for in "extent" property) 10 xthresh = 0.1; 11 12 n = length(x); 13 if ~iscell(txt), txt={txt}; end 14 15 if length(y)~=n || length(txt)~=n, error('length mismatch between x,y,txt'); end 16 17 h = text(x,y,txt,varargin{:}); 18 19 yl=ylim; ytot=diff(yl); 20 xl=xlim; xtot=diff(xl); 21 22 maxtries = 100; 23 for t=1:maxtries 24 ext = nan(n,4); 25 for i=1:n, ext(i,:) = get(h(i),'extent'); end 26 xstart=ext(:,1); xsz=ext(:,3); xend=xstart+xsz; 27 ystart=ext(:,2); ysz=ext(:,4); yend=ystart+ysz; 28 overlapx = zeros(n,n); 29 overlapy = zeros(n,n); 30 for i1=1:n-1, for i2=i1+1:n 31 if xstart(i1)<=xend(i2)&xstart(i2)<=xend(i1) 32 overlapx(i1,i2)=(min(xend(i2)-xstart(i1),xend(i1)-xstart(i2)))/(min(xsz(i1),xsz(i2))); 33 end 34 if ystart(i1)<=yend(i2)&ystart(i2)<=yend(i1) 35 overlapy(i1,i2)=(min(yend(i2)-ystart(i1),yend(i1)-ystart(i2)))/(min(ysz(i1),ysz(i2))); 36 end 37 end,end 38 overlapmax = max(overlapx,overlapy); 39 ov = (overlapx>xthresh & overlapy>ythresh); 40 [o1 o2] = find(ov); 41 if isempty(o1), break; end 42 [tmp ord] = sort(overlapmax(find(ov))); 43 o1=o1(ord); o2=o2(ord); 44 moved = false(n,1); 45 for i=1:length(o1), i1=o1(i); i2=o2(i); 46 if moved(i1) || moved(i2), continue; end 47 pos1 = get(h(i1),'position'); 48 pos2 = get(h(i2),'position'); 49 oy = overlapy(i1,i2)*min(ysz(i1),ysz(i2)); 50 ox = overlapx(i1,i2)*min(xsz(i1),xsz(i2)); 51 if oy/ytot < ox/xtot % overlapy is easier to fix 52 shift = 0.5*(1-ythresh)*oy; 53 if ystart(i1)<ystart(i2) % i1 above i2 54 pos1(2)=pos1(2)-shift; pos2(2)=pos2(2)+shift; 55 else % i1 below i2 56 pos1(2)=pos1(2)+shift; pos2(2)=pos2(2)-shift; 57 end 58 else % overlapx is easier to fix 59 shift = 0.5*(1-xthresh)*ox; 60 if xstart(i1)<xstart(i2) % i1 left of i2 61 pos1(1)=pos1(1)-shift; pos2(1)=pos2(1)+shift; 62 else % i1 right of i2 63 pos1(1)=pos1(1)+shift; pos2(1)=pos2(1)-shift; 64 end 65 end 66 set(h(i1),'position',pos1); 67 set(h(i2),'position',pos2); 68 moved([i1 i2]) = true; 69 end 70 end 71 72 if nargout==0, clear h, end