1 |
function [CSO,H] = contourfill(arg1,arg2,arg3,arg4) |
---|
2 |
% CONTOURFILL Filled contour plot |
---|
3 |
% CONTOURFILL(Z) is a filled contour plot of matrix Z treating the |
---|
4 |
% values in Z as heights above a plane. |
---|
5 |
% |
---|
6 |
% CONTOURFILL(X,Y,Z), where X and Y are vectors, specifies X- and |
---|
7 |
% Y- axes used on the plot. X and Y can also be matrices of the |
---|
8 |
% same size as Z, in which case they specify a surface in an |
---|
9 |
% identical manner as SURFACE. |
---|
10 |
% |
---|
11 |
% CONTOURFILL(Z,N) and CONTOURFILL(X,Y,Z,N) draw N contour lines, |
---|
12 |
% overriding the default automatic value. |
---|
13 |
% |
---|
14 |
% CONTOURFILL(Z,V) and CONTOURFILL(X,Y,Z,V) draw LENGTH(V) contour |
---|
15 |
% lines at the values specified in vector V. |
---|
16 |
% |
---|
17 |
% CONTOURFILL([X Y],N,Z,V) contour fills the triangular mesh |
---|
18 |
% specified by node location vectors X,Y with height vector Z, |
---|
19 |
% where N is a 3xn matrix containing the node indices for n |
---|
20 |
% triangles. |
---|
21 |
|
---|
22 |
% Author: R. Pawlowicz (IOS) rich@ios.bc.ca |
---|
23 |
% 14/12/94 |
---|
24 |
|
---|
25 |
recmesh=1; |
---|
26 |
|
---|
27 |
if (nargin == 4), |
---|
28 |
x = arg1; |
---|
29 |
y = arg2; |
---|
30 |
z = arg3; |
---|
31 |
nv = arg4; |
---|
32 |
if min(size(z))==1 & any(size(y)==3), % fall-through for triangular mesh |
---|
33 |
recmesh=0; |
---|
34 |
else |
---|
35 |
if (size(y,1)==1), y=y'; end; |
---|
36 |
if (size(x,2)==1), x=x'; end; |
---|
37 |
[mz,nz] = size(z); |
---|
38 |
end; |
---|
39 |
elseif (nargin == 3), |
---|
40 |
x = arg1; |
---|
41 |
y = arg2; |
---|
42 |
z = arg3; |
---|
43 |
nv = []; |
---|
44 |
if min(size(z))==1 & any(size(y)==3), % fall-through for triangular mesh |
---|
45 |
recmesh=0; |
---|
46 |
else |
---|
47 |
if (size(y,1)==1), y=y'; end; |
---|
48 |
if (size(x,2)==1), x=x'; end; |
---|
49 |
[mz,nz] = size(z); |
---|
50 |
end; |
---|
51 |
elseif (nargin == 2), |
---|
52 |
[mz,nz] = size(arg1); |
---|
53 |
x = 1:nz; |
---|
54 |
y = [1:mz]'; |
---|
55 |
z = arg1; |
---|
56 |
nv = arg2; |
---|
57 |
elseif (nargin == 1), |
---|
58 |
[mz,nz] = size(arg1); |
---|
59 |
x = 1:nz; |
---|
60 |
y = [1:mz]'; |
---|
61 |
z = arg1; |
---|
62 |
nv = []; |
---|
63 |
end |
---|
64 |
|
---|
65 |
i = find(finite(z)); |
---|
66 |
minz = min(min(z(i))); |
---|
67 |
maxz = max(max(z(i))); |
---|
68 |
|
---|
69 |
% Generate default contour levels if they aren't specified |
---|
70 |
nv=getlevels(z,nv); |
---|
71 |
|
---|
72 |
% Handle interior holes correctly |
---|
73 |
draw_min=0; |
---|
74 |
if any(nv<=minz), |
---|
75 |
draw_min=1; |
---|
76 |
end; |
---|
77 |
|
---|
78 |
% Get the unique levels |
---|
79 |
|
---|
80 |
if (recmesh), |
---|
81 |
% Get the unique levels |
---|
82 |
|
---|
83 |
nv = sort([minz nv maxz]); |
---|
84 |
zi = [1, find(diff(nv))+1]; |
---|
85 |
nv = nv(zi); |
---|
86 |
% Surround the matrix by a very low region to get closed contours, and |
---|
87 |
% replace any NaN with low numbers as well. |
---|
88 |
|
---|
89 |
zz=[ NaN+ones(1,nz+2) ; NaN+ones(mz,1) z NaN+ones(mz,1) ; NaN+ones(1,nz+2)]; |
---|
90 |
kk=find(isnan(zz(:))); |
---|
91 |
zz(kk)=minz-1e4*(maxz-minz)+zeros(size(kk)); |
---|
92 |
|
---|
93 |
xx = [2*x(:,1)-x(:,2), x, 2*x(:,nz)-x(:,nz-1)]; |
---|
94 |
yy = [2*y(1,:)-y(2,:); y; 2*y(mz,:)-y(mz-1,:)]; |
---|
95 |
if (min(size(yy))==1), |
---|
96 |
CS=contoursurf(xx,yy,zz,nv); |
---|
97 |
else |
---|
98 |
CS=contoursurf(xx([ 1 1:mz mz],:),yy(:,[1 1:nz nz]),zz,nv); |
---|
99 |
end; |
---|
100 |
else |
---|
101 |
CS=contourtri(x,z,y,nv,'fill'); |
---|
102 |
end; |
---|
103 |
|
---|
104 |
if length(CS)==0, return; end; % No contours to be drawn! |
---|
105 |
|
---|
106 |
% Find the indices of the curves in the c matrix, and get the |
---|
107 |
% area of closed curves in order to draw patches correctly. |
---|
108 |
ii = 1; |
---|
109 |
ncurves = 0; |
---|
110 |
I = []; |
---|
111 |
Area=[]; |
---|
112 |
while (ii < size(CS,2)), |
---|
113 |
nl=CS(2,ii); |
---|
114 |
ncurves = ncurves + 1; |
---|
115 |
I(ncurves) = ii; |
---|
116 |
x=CS(1,ii+[1:nl]); % First patch |
---|
117 |
y=CS(2,ii+[1:nl]); |
---|
118 |
Area(ncurves)=sum( diff(x).*(y(1:nl-1)+y(2:nl))/2 ); |
---|
119 |
ii = ii + nl + 1; |
---|
120 |
end |
---|
121 |
|
---|
122 |
plot(CS(1,2),CS(2,2),'-'); |
---|
123 |
|
---|
124 |
% Plot patches in order of decreasing size. This makes sure that |
---|
125 |
% all the levels get drawn, no matter if we are going up a hill or |
---|
126 |
% down into a hole. When going down we shift levels - you can |
---|
127 |
% tell whether we are going up or down by checking the sign of the |
---|
128 |
% area (since curves are oriented so that the high side is always |
---|
129 |
% the same side). Lowest curve is largest and always encloses higher |
---|
130 |
% data |
---|
131 |
|
---|
132 |
H=[]; |
---|
133 |
[FA,IA]=sort(-abs(Area)); |
---|
134 |
|
---|
135 |
for jj=IA, |
---|
136 |
nl=CS(2,I(jj)); |
---|
137 |
lev=CS(1,I(jj)); |
---|
138 |
if (lev ~=minz | draw_min ), |
---|
139 |
x=CS(1,I(jj)+[1:nl]); |
---|
140 |
y=CS(2,I(jj)+[1:nl]); |
---|
141 |
if (sign(Area(jj)) ~=sign(Area(IA(1))) ), |
---|
142 |
kk=find(nv==lev); |
---|
143 |
if (kk>1+sum(nv<=minz)*(~draw_min)), |
---|
144 |
lev=nv(kk-1); |
---|
145 |
else |
---|
146 |
lev=NaN; % missing data section |
---|
147 |
end; |
---|
148 |
end; |
---|
149 |
|
---|
150 |
if (finite(lev)), |
---|
151 |
H=[H;patch(x,y,lev,'facecolor','flat','edgecolor','none')]; |
---|
152 |
else |
---|
153 |
H=[H;patch(x,y,lev,'facecolor',get(gcf,'color'),'edgecolor','none')]; |
---|
154 |
end; |
---|
155 |
end; |
---|
156 |
end; |
---|
157 |
|
---|
158 |
if nargout |
---|
159 |
CSO=CS; |
---|
160 |
end |
---|