📄 clabel.m
字号:
function hh = clabel(cs,varargin)%CLABEL Contour plot elevation labels.% CLABEL(CS,H) adds height labels to the current contour% plot. The labels are rotated and inserted within the contour% lines. CS and H are the contour matrix output and object handle% outputs from CONTOUR, CONTOUR3, or CONTOURF.%% CLABEL(CS,H,V) labels just those contour levels given in% vector V. The default action is to label all known contours.% The label positions are selected randomly.%% CLABEL(CS,H,'manual') places contour labels at the locations% clicked on with a mouse. Pressing the return key terminates% labeling. Use the space bar to enter contours and the arrow% keys to move the crosshair if no mouse is available.%% CLABEL(CS) or CLABEL(CS,V) or CLABEL(CS,'manual') places% contour labels as above, except that the labels are drawn as% plus signs on the contour with a nearby height value.%% H = CLABEL(...) returns handles to the TEXT (and possibly LINE)% objects created. The UserData property of the TEXT objects contain% the height value for each label.%% Text property/value pairs can be appended to the list of % input arguments in the above:% CLABEL(clabel options, 'text property', property_value , ... )%% One special property ('label') is also available to specify % the spacing between labels (in points). This defaults to 144, or% 2 inches. %% Example% subplot(1,3,1), [cs,h] = contour(peaks); clabel(cs,h,'label',72)% subplot(1,3,2), cs = contour(peaks); clabel(cs)% subplot(1,3,3), [cs,h] = contour(peaks); % clabel(cs,h,'fontsize',15,'color','r','rotation',0)%% See also CONTOUR, CONTOUR3, CONTOURF, LINELABEL.% Thanks to R. Pawlowicz (IOS) rich@ios.bc.ca for the algorithm used% in 'inline_labels' so that clabel can produce inline labeling.% Copyright (c) 1984-96 by The MathWorks, Inc.% $Revision: 5.19 $ $Date: 1996/10/25 17:43:58 $% Modified by R Pawlowicz to allow for text properties as in extcontour code 14/5/97% 28/10/97 - modified to work in map contouring% 9/01/98 - improved calculation of gaps for line labels% Fix by Eric Firing, efiring@soest.hawaii.edu, 4/97, to% make the rotation angles correct when XDir and/or YDir are% reverse.if nargin == 0 error('Not enough input arguments.')endif min(size(cs)) > 2 error('First input must be a valid contour description matrix.')endthreeD = IsThreeD(gca);if nargin == 1, h = plus_labels(threeD,cs);else if ~isempty(varargin{1}(1)) & ishandle(varargin{1}(1)) & ... (strcmp(get(varargin{1}(1),'type'),'line') | strcmp(get(varargin{1}(1),'type'),'patch')), h = inline_labels(cs,varargin{:}); else h = plus_labels(threeD,cs,varargin{:}); end;end;if nargout>0, hh = h; endif ~ishold, if threeD, view(3), else view(2), endend%--------------------------------------------------------------function H = inline_labels(CS,h,varargin)%% Draw the labels along the contours and rotated to match the local slope.%% To open up space in the contours, we rely on the order in which% the handles h are created in CONTOUR3. If CONTOUR3 changes you% might need to change the algorithm below.% Author: R. Pawlowicz IOS rich@ios.bc.ca% 12/12/94% changes - R. Pawlowicz 14/5/97 - small bug in "that ole' matlab magic" fixed,% also another in manual selection of locations.manual=0; v=[]; inargs=zeros(1,length(varargin));if nargin>=3 & isstr(varargin{1}) & strcmp(varargin{1},'manual'), manual = 1; inargs(1)=1;endif ~manual & nargin>=3 & ~isstr(varargin{1}), v = varargin{1}; inargs(1)=1;end;lab_int=72*2; % label interval (points)for k=find(inargs==0), if isstr(varargin{k}) & ~isempty(findstr(varargin{k},'lab')), inargs([k k+1])=1; lab_int=varargin{k+1}; end;end;varargin(find(inargs))=[]; if strcmp(get(h(1),'type'),'patch') & ~strcmp(get(h(1),'facecolor'),'none'), isfilled = 1;else isfilled = 0;end%% EF 4/97if (strcmp(get(gca, 'XDir'), 'reverse')), XDir = -1; else XDir = 1; endif (strcmp(get(gca, 'YDir'), 'reverse')), YDir = -1; else YDir = 1; end%%% Compute scaling to make sure printed output looks OK. We have to go via% the figure's 'paperposition', rather than the the absolute units of the% axes 'position' since those would be absolute only if we kept the 'units'% property in some absolute units (like 'points') rather than the default% 'normalized'.UN=get(gca,'units');if (UN(1:3)=='nor'), UN=get(gcf,'paperunits'); set(gcf,'paperunits','points'); PA=get(gcf,'paperposition'); set(gcf,'paperunits',UN); PA=PA.*[get(gca,'position')];else set(gca,'units','points'); PA=get(gca,'pos'); set(gca,'units',UN); end; % Find beginning of all lineslCS=size(CS,2);if ~isempty(get(gca,'children')), XL=get(gca,'xlim'); YL=get(gca,'ylim');else iL=[]; k=1; XL=[Inf -Inf]; YL=[Inf -Inf]; while (k<lCS), x=CS(1,k+(1:CS(2,k))); y=CS(2,k+(1:CS(2,k))); XL=[ min([XL(1),x]) max([XL(2),x]) ]; YL=[ min([YL(1),y]) max([YL(2),y]) ]; iL=[iL k]; k=k+CS(2,k)+1; end; set(gca,'xlim',XL,'ylim',YL);end;Aspx=PA(3)/diff(XL); % To convert data coordinates to paper (we need % to do thisAspy=PA(4)/diff(YL); % to get the gaps for text the correct size)H=[];% Set up a dummy text object from which you can get text extent infoH1=text(XL(1),YL(1),'dummyarg','units','points','visible','off',varargin{:});% Decompose contour data structure if manual mode.if manual disp(' '), disp(' Please wait a moment...') x = []; y = []; ilist = []; klist = []; plist = []; ii = 0; k = 0; n = 0; while (1) k = k + 1; ii = ii + n + 1; if ii > lCS, break, end c = CS(1,ii); n = CS(2,ii); nn = 2 .* n -1; xtemp = zeros(nn, 1); ytemp = zeros(nn, 1); xtemp(1:2:nn) = CS(1, ii+1:ii+n); xtemp(2:2:nn) = (xtemp(1:2:nn-2) + xtemp(3:2:nn)) ./ 2; ytemp(1:2:nn) = CS(2, ii+1:ii+n); ytemp(2:2:nn) = (ytemp(1:2:nn-2) + ytemp(3:2:nn)) ./ 2; x = [x; xtemp]; y = [y; ytemp]; % Keep these. ilist = [ilist; ii(ones(nn,1))]; klist = [klist; k(ones(nn,1))]; plist = [plist; (1:.5:n)']; end ax = axis; xmin = ax(1); xmax = ax(2); ymin = ax(3); ymax = ax(4); xrange = xmax - xmin; yrange = ymax - ymin; xylist = (x .* yrange + sqrt(-1) .* y .* xrange); view(2) disp(' '); disp(' Carefully select contours for labeling.') disp(' When done, press RETURN while the Graph window is the active window.')end% Get labels all at once to get the length of the longest string. % This allows us to call extent only once, thus speeding up this routineif ~manual, labels = getlabels(CS); % Get the size of the label set(H1,'string',repmat('9',1,size(labels,2)),'visible','on',varargin{:}) EX=get(H1,'extent'); set(H1,'visible','off') len_lab=EX(3)/2;endii=1; k = 0;levels = []; positions = [];while (ii<lCS), if manual [xx, yy, button] = ginput(1); if isempty(button) | isequal(button,13), break, end if xx < xmin | xx > xmax, break, end if yy < ymin | yy > ymax, break, end xy = xx .* yrange + sqrt(-1) .* yy .* xrange; dist = abs(xylist - xy); f = find(dist == min(dist)); if ~isempty(f) f = f(1); ii = ilist(f); k = klist(f); p = floor(plist(f)); end else k = k+1; end if ~isfilled & k>length(h), error('Not enough contour handles.'); end l=CS(2,ii); x=CS(1,ii+(1:l)); y=CS(2,ii+(1:l)); lvl=CS(1,ii); if manual lab=num2str(lvl); % Get the size of the label set(H1,'string',lab,'visible','on',varargin{:}) EX=get(H1,'extent'); set(H1,'visible','off') len_lab=EX(3)/2; else %RP - get rid of all blanks in label lab=labels(k,labels(k,:)~=' '); %RP - scale label length by string size instead of a fixed length len_lab=EX(3)/2*length(lab)/size(labels,2); end % RP28/10/97 - Contouring sometimes returns x vectors with NaN in them - we want to handle % this case! sx=x*Aspx; sy=y*Aspy; d=[0 sqrt(diff(sx).^2 +diff(sy).^2) ];d(isnan(d))=0; d=cumsum(d); if ~manual psn=[max(len_lab,lab_int+lab_int*(rand(1)-.5)):lab_int:d(l)-len_lab]; else psn = min(max(max(d(p),d(2)+eps*d(2)),d(1)+len_lab),d(end)-len_lab);%%RP levels = [levels;lvl]; levels = [levels;ii]; positions = [positions;psn];%%RP kk = find(levels==lvl) kk = find(levels==ii); psn = positions(kk)'; end lp=size(psn,2); if (lp>0) & isfinite(lvl) & ... (isempty(v) | any(abs(lvl-v)/max(eps+abs(v)) < .00001)), Ic=sum( d(ones(1,lp),:)' < psn(ones(1,l),:) ); Il=sum( d(ones(1,lp),:)' <= psn(ones(1,l),:)-len_lab );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -