


Melissa Day 5/24/2013
Upgrade of Andrew Diamond's quiverc2wcmap to generate a quiver plot
with arrows colored according to vector magnitude.
Functional differences from quiverc2wcmap:
1) Allows user to specify colormap boundaries using 'bound': changes
colorbar axes AND corresponding vector coloring
(much more useful for intercomparison of datasets)
2) Improved fidelity to magnitude colors in large datasets
(at a cost of increased computation time...)
Uses some improvements from DS's vfield_color
3) Small clarifications added
Example:
x = rand(1,50).*100;
y = rand(1,50).*100;
u = rand(1,50) .* 10;
v = rand(1,50) .* 10;
scale = 0;
figure; quiverwcolorbar(x',y',u',v',scale); %compare to:
figure; quiverwcolorbar(x',y',u',v',scale,'bounds',[0 10]);
----------------
function hh = quiverc2wcmap(varargin)
Andrew Diamond 3/17/2005
This is based off of Tobias H�fken which was based off of Bertrand Dano
keeping with their main intent to show a color w/r to magnitude quiver plot
while maintaining a large amount of quiver API backwards compatability.
Functional differences from quiverc2:
1) This works under 6.5.1
2) It handles NaNs
3) It draws a colormap that is w/r to the quiver magnitudes (hard coded to
20 segments of the colormap as per quiverc2 - seems fine for a quiver).
4) Various bug fixes (I think)
In order to do this I needed some small hacks on 6.5.1's quiver to take a
color triplet. I have included as part of this file in a subfunction below.
----------------
Comments from quiverc2
changed Tobias H�fken 3-14-05
totally downstripped version of the former
split input field into n segments and do a quiver qhich each of them


0001 function hh = quiverwcolorbar(varargin) 0002 % Melissa Day 5/24/2013 0003 % Upgrade of Andrew Diamond's quiverc2wcmap to generate a quiver plot 0004 % with arrows colored according to vector magnitude. 0005 % Functional differences from quiverc2wcmap: 0006 % 1) Allows user to specify colormap boundaries using 'bound': changes 0007 % colorbar axes AND corresponding vector coloring 0008 % (much more useful for intercomparison of datasets) 0009 % 2) Improved fidelity to magnitude colors in large datasets 0010 % (at a cost of increased computation time...) 0011 % Uses some improvements from DS's vfield_color 0012 % 3) Small clarifications added 0013 % Example: 0014 % x = rand(1,50).*100; 0015 % y = rand(1,50).*100; 0016 % u = rand(1,50) .* 10; 0017 % v = rand(1,50) .* 10; 0018 % scale = 0; 0019 % figure; quiverwcolorbar(x',y',u',v',scale); %compare to: 0020 % figure; quiverwcolorbar(x',y',u',v',scale,'bounds',[0 10]); 0021 %---------------- 0022 % function hh = quiverc2wcmap(varargin) 0023 % Andrew Diamond 3/17/2005 0024 % This is based off of Tobias H�fken which was based off of Bertrand Dano 0025 % keeping with their main intent to show a color w/r to magnitude quiver plot 0026 % while maintaining a large amount of quiver API backwards compatability. 0027 % Functional differences from quiverc2: 0028 % 1) This works under 6.5.1 0029 % 2) It handles NaNs 0030 % 3) It draws a colormap that is w/r to the quiver magnitudes (hard coded to 0031 % 20 segments of the colormap as per quiverc2 - seems fine for a quiver). 0032 % 4) Various bug fixes (I think) 0033 % In order to do this I needed some small hacks on 6.5.1's quiver to take a 0034 % color triplet. I have included as part of this file in a subfunction below. 0035 %---------------- 0036 % Comments from quiverc2 0037 % changed Tobias H�fken 3-14-05 0038 % totally downstripped version of the former 0039 % split input field into n segments and do a quiver qhich each of them 0040 0041 % Modified version of Quiver to plots velocity vectors as arrows 0042 % with components (u,v) at the points (x,y) using the current colormap 0043 0044 % Bertrand Dano 3-3-03 0045 % Copyright 1984-2002 The MathWorks, Inc. 0046 0047 % changed T. H�fken 14.03.05, for high data resolution 0048 % using fixed color "spacing" of 20 0049 0050 %QUIVERC Quiver color plot. 0051 % QUIVERC(X,Y,U,V) plots velocity vectors as arrows with components (u,v) 0052 % at the points (x,y). The matrices X,Y,U,V must all be the same size 0053 % and contain corresponding position and velocity components (X and Y 0054 % can also be vectors to specify a uniform grid). QUIVER automatically 0055 % scales the arrows to fit within the grid. 0056 % 0057 % QUIVERC(U,V) plots velocity vectors at equally spaced points in 0058 % the x-y plane. 0059 % 0060 % QUIVERC(U,V,S) or QUIVER(X,Y,U,V,S) automatically scales the 0061 % arrows to fit within the grid and then stretches them by S. Use 0062 % S=0 to plot the arrows without the automatic scaling. 0063 % 0064 % QUIVERC(...,LINESPEC) uses the plot linestyle specified for 0065 % the velocity vectors. Any marker in LINESPEC is drawn at the base 0066 % instead of an arrow on the tip. Use a marker of '.' to specify 0067 % no marker at all. See PLOT for other possibilities. 0068 % 0069 % QUIVERC(...,'filled') fills any markers specified. 0070 % 0071 % H = QUIVERC(...) returns a vector of line handles. 0072 % 0073 % Example: 0074 % [x,y] = meshgrid(-2:.2:2,-1:.15:1); 0075 % z = x .* exp(-x.^2 - y.^2); [px,py] = gradient(z,.2,.15); 0076 % contour(x,y,z), hold on 0077 % quiverc(x,y,px,py), hold off, axis image 0078 % 0079 % See also FEATHER, QUIVER3, PLOT. 0080 % Clay M. Thompson 3-3-94 0081 % Copyright 1984-2002 The MathWorks, Inc. 0082 % $Revision: 5.21 $ $Date: 2002/06/05 20:05:16 $ 0083 %------------------------------------------------------------- 0084 nin = nargin; %number of inputs 0085 0086 % error(nargchk(2,5,nin)); 0087 error(nargchk(2,7,nin)); %added +2 to maxargs to account for 'bounds' add 0088 0089 % Check numeric input arguments 0090 if nin<4, % quiver(u,v) or quiver(u,v,s) 0091 [msg,x,y,u,v] = xyzchk(varargin{1:2}); 0092 else % quiver(x,y,u,v) and beyond 0093 [msg,x,y,u,v] = xyzchk(varargin{1:4}); 0094 end 0095 if ~isempty(msg), error(msg); end 0096 0097 scale=1; % This is the default I think. 0098 if(nin == 3) % quiver(u,v,s) 0099 if(isscalar(varargin{nin})) 0100 scale = varargin{nin}; 0101 end 0102 elseif(nin >= 5) % quiver(x,y,u,v,s) or quiver(x,y,u,v,s,'bounds',[start end]) 0103 if(isscalar(varargin{5})) 0104 scale = varargin{5}; 0105 end 0106 end 0107 0108 %-------------Define matrix of vector magnitudes------------- 0109 % Define matrix of vector magnitudes 0110 vr = sqrt(u.^2+v.^2); 0111 0112 % From quiverc2wcmap: 0113 % if data has Nan, don't let it contaminate the computations that segment the 0114 % data; I could just do this with vr and then get clever with the indices but 0115 % this make for easy debugging and as this is a graphics routine the computation 0116 % time is completely irrelevant. 0117 nonNaNind = find(~isnan(vr(:))); 0118 xyuvvrNN = [x(nonNaNind),y(nonNaNind),u(nonNaNind),v(nonNaNind),vr(nonNaNind)]; 0119 [xyuvvrNNs, xyuvvrNNsi] = sortrows(xyuvvrNN,5); 0120 0121 % From quiverc2wcmap, no longer necessary 0122 % n = 20; %number of colors 0123 % CC = colormap; 0124 % iCCs=round(linspace(1,size(CC,1),n)); 0125 % iData = round(linspace(0,size(xyuvvrNNs,1),n+1)); 0126 % figure; 0127 0128 %-------------Generate colorbar------------- 0129 % Includes a clever way to generate (and subsequently hide) an image that 0130 % is required for colorbar without running out of memory for large datasets. 0131 % 0132 % Condensed comments from quiverc2wcmap: 0133 % In 6.5.1 if you ever want a colorbar tick marks to reflect real data ranges 0134 % (versus just the indices of a colormap) then there apparently has to be an 0135 % image somewhere in the figure. Of course, I don't want an image but I figured 0136 % I just make it invisible and then draw the quiver plot over it. 0137 % Unfortunately, it seems that colorbar uses caxis to retrive the data range in 0138 % the image and for invisible images it always seems to be 0 UNLESS you 0139 % explictly reset the caxis. 0140 % This will work but then the axis will be oversized to accomodate the image 0141 % because images have their first and last vitual "pixels" CENTERED around the 0142 % implicit or explict xmin,xmax,ymin,ymax (as per imagesc documentation) but the 0143 % start and end of each of these "pixels" is +/- half a unit where the unit 0144 % corresponds to subdividing the limits by the number of pixels (-1). Given 0145 % that formula and given my invisible 2x2 image for which it is desired to 0146 % diplay in an axis that ISN'T oversized (i.e. min(x), max(x), min(y),max(y)) it 0147 % is possible to solve for the limits (i.e. an artifically reduced limit) 0148 % that need to be specified for imagesc to make its final oversized axis to be the 0149 % non oversized axis that we really want. 0150 % xa,xb,ya,yb compenstates for the axis extention given by imagesc to make 0151 % pixels centered at the limit extents (etc.). Note, this "easy" 0152 % formula would only work for 2x2 pixel images. 0153 0154 xs = min(x); %x(1); 0155 xf = max(x); %x(end) 0156 xa = (3 * xs + xf)/4; 0157 xb = (3 * xf + xs)/4; 0158 ys = min(y); %y(1); 0159 yf = max(y); %y(end) 0160 ya = (3 * ys + yf)/4; 0161 yb = (3 * yf + ys)/4; 0162 0163 % Determine magnitude min/max (which is reflected in colorbar) 0164 colormin = min(xyuvvrNNs(:,5)); %column 5 is NaN-cleared vr 0165 colormax = max(xyuvvrNNs(:,5)); 0166 0167 % Allow user to edit bounds using "'bounds',[colormin colormax]" input 0168 for k=1:nin 0169 if (k~=nin) && (length(varargin{k})==6) && strcmp(varargin{k},'bounds') 0170 bounds = varargin{k+1}; 0171 if isempty(bounds), error('Specify colormap boundaries'); end 0172 colormin = bounds(1); 0173 colormax = bounds(2); 0174 end 0175 end 0176 % mapbounds = reshape(xyuvvrNNs([1,end;1,end],5),2,2); %from quiverc2wcmap 0177 mapbounds = [colormin colormax; colormin colormax]; 0178 h=imagesc([xa,xb],[ya,yb],mapbounds); 0179 set(h,'visible','off'); 0180 0181 % Prep colorbar 0182 rang = (colormax-colormin)/colormax; 0183 ticknum = 6; %if you want to toggle number of ticks on colorbar 0184 incr = rang./(ticknum-1); 0185 B = [colormin/colormax:incr:1]; 0186 B = B.*colormax; 0187 C = sprintf(['%4.2e',repmat([' \n%4.2e'], 1, ticknum)],B); 0188 C = str2num(C); 0189 caxis([colormin colormax]) 0190 colorbar('EastOutside','ytick',B,'yticklabel',C,... 0191 'ticklength',[0.04 0.1],'YLim',[B(1) B(ticknum)],'FontSize',20) 0192 0193 % In quiverc2wcmap this loop plotted for each color level (n=20) and was very 0194 % fast, but I found it did not plot some large data sets with enough color 0195 % accuracy. Switched the loop to examine each data point individually. 0196 % Takes longer but I'm more confident that the colors are correct. Note: 0197 % much of this overhaul was inspired by DS's vfield_color. 0198 hold on; 0199 cmap = jet(64); %toggle type of colormap 0200 CC = colormap(cmap); 0201 cm_stepsize = (colormax-colormin)/length(CC); 0202 for it=1:size(xyuvvrNNs,1) %takes ~13 seconds for a 8730-point dataset 0203 % Some quiverc2wcmap fragments for reference: 0204 % for it=1:n %10x faster, but may not be accurate 0205 % c = CC(iCCs(it),:); %colormap([1:64](it),:) %ie "This RGB color row =" 0206 % si = iData(it)+1; %[1:size(data)](it)+1; %ie "This start row" 0207 % ei = iData(it+1); %[1:size(data)](it+1); %ie "This end row" 0208 % hh=quiver(xyuvvrNNs(si:ei,1),xyuvvrNNs(si:ei,2),... 0209 % xyuvvrNNs(si:ei,3),xyuvvrNNs(si:ei,4),scale*it/n,'Color',c) 0210 cm_index = floor( (xyuvvrNNs(it,5) - colormin) / ( cm_stepsize ) ) + 1; 0211 if cm_index == 1 %in case colormin is zero 0212 c = CC(cm_index,:); 0213 elseif cm_index > length(CC) %in case max(xyuvvrNNs) > colormax 0214 cm_index = length(CC); 0215 c = CC(cm_index,:); 0216 elseif cm_index <= 0 %in case min(xyuvvrNNs) < colormin 0217 cm_index = 1; 0218 c = CC(cm_index,:); 0219 else 0220 cm_index = cm_index-1; 0221 c = CC(cm_index,:); 0222 end 0223 hh=quiver(xyuvvrNNs(it,1),xyuvvrNNs(it,2),... 0224 xyuvvrNNs(it,3),xyuvvrNNs(it,4),scale,'Color',c); 0225 end 0226 0227 0228 %----------Rest of document is from quiverc2wcmap--------------- 0229 % This is Matlab's 6.5.1 quiver. I figure that ensures a fair amouint of backward 0230 % compatibility but I needed to hack it to allow a 'Color' property. Obviously 0231 % a person could do more. 0232 0233 function hh = quiver(varargin) 0234 %QUIVER Quiver plot. 0235 % QUIVER(X,Y,U,V) plots velocity vectors as arrows with components (u,v) 0236 % at the points (x,y). The matrices X,Y,U,V must all be the same size 0237 % and contain corresponding position and velocity components (X and Y 0238 % can also be vectors to specify a uniform grid). QUIVER automatically 0239 % scales the arrows to fit within the grid. 0240 % 0241 % QUIVER(U,V) plots velocity vectors at equally spaced points in 0242 % the x-y plane. 0243 % 0244 % QUIVER(U,V,S) or QUIVER(X,Y,U,V,S) automatically scales the 0245 % arrows to fit within the grid and then stretches them by S. Use 0246 % S=0 to plot the arrows without the automatic scaling. 0247 % 0248 % QUIVER(...,LINESPEC) uses the plot linestyle specified for 0249 % the velocity vectors. Any marker in LINESPEC is drawn at the base 0250 % instead of an arrow on the tip. Use a marker of '.' to specify 0251 % no marker at all. See PLOT for other possibilities. 0252 % 0253 % QUIVER(...,'filled') fills any markers specified. 0254 % 0255 % H = QUIVER(...) returns a vector of line handles. 0256 % 0257 % Example: 0258 % [x,y] = meshgrid(-2:.2:2,-1:.15:1); 0259 % z = x .* exp(-x.^2 - y.^2); [px,py] = gradient(z,.2,.15); 0260 % contour(x,y,z), hold on 0261 % quiver(x,y,px,py), hold off, axis image 0262 % 0263 % See also FEATHER, QUIVER3, PLOT. 0264 0265 % Clay M. Thompson 3-3-94 0266 % Copyright 1984-2002 The MathWorks, Inc. 0267 % $Revision: 5.21 $ $Date: 2002/06/05 20:05:16 $ 0268 0269 % Arrow head parameters 0270 alpha = 0.33; % Size of arrow head relative to the length of the vector 0271 beta = 0.33; % Width of the base of the arrow head relative to the length 0272 autoscale = 1; % Autoscale if ~= 0 then scale by this. 0273 plotarrows = 1; % Plot arrows 0274 sym = ''; 0275 0276 filled = 0; 0277 ls = '-'; 0278 ms = ''; 0279 col = 'b'; 0280 0281 nin = nargin; 0282 ColorSpecInd = find(strcmpi(varargin, 'color')); 0283 if(length(ColorSpecInd)==1 & nin > ColorSpecInd) 0284 col = varargin{ColorSpecInd+1}; 0285 varargin = varargin([1:ColorSpecInd-1,ColorSpecInd+2:nin]); 0286 nin = nin-2; 0287 end 0288 % Parse the string inputs 0289 while isstr(varargin{nin}), 0290 vv = varargin{nin}; 0291 if ~isempty(vv) & strcmp(lower(vv(1)),'f') 0292 filled = 1; 0293 nin = nin-1; 0294 else 0295 [l,c,m,msg] = colstyle(vv); 0296 if ~isempty(msg), 0297 error(sprintf('Unknown option "%s".',vv)); 0298 end 0299 if ~isempty(l), ls = l; end 0300 if ~isempty(c), col = c; end 0301 if ~isempty(m), ms = m; plotarrows = 0; end 0302 if isequal(m,'.'), ms = ''; end % Don't plot '.' 0303 nin = nin-1; 0304 end 0305 end 0306 0307 error(nargchk(2,5,nin)); 0308 0309 % Check numeric input arguments 0310 if nin<4, % quiver(u,v) or quiver(u,v,s) 0311 [msg,x,y,u,v] = xyzchk(varargin{1:2}); 0312 else 0313 [msg,x,y,u,v] = xyzchk(varargin{1:4}); 0314 end 0315 if ~isempty(msg), error(msg); end 0316 0317 if nin==3 | nin==5, % quiver(u,v,s) or quiver(x,y,u,v,s) 0318 autoscale = varargin{nin}; 0319 end 0320 0321 % Scalar expand u,v 0322 if prod(size(u))==1, u = u(ones(size(x))); end 0323 if prod(size(v))==1, v = v(ones(size(u))); end 0324 0325 if autoscale, 0326 % Base autoscale value on average spacing in the x and y 0327 % directions. Estimate number of points in each direction as 0328 % either the size of the input arrays or the effective square 0329 % spacing if x and y are vectors. 0330 if min(size(x))==1, n=sqrt(prod(size(x))); m=n; else [m,n]=size(x); end 0331 delx = diff([min(x(:)) max(x(:))])/n; 0332 dely = diff([min(y(:)) max(y(:))])/m; 0333 del = delx.^2 + dely.^2; 0334 if del>0 0335 len = sqrt((u.^2 + v.^2)/del); 0336 maxlen = max(len(:)); 0337 else 0338 maxlen = 0; 0339 end 0340 0341 if maxlen>0 0342 autoscale = autoscale*0.9 / maxlen; 0343 else 0344 autoscale = autoscale*0.9; 0345 end 0346 u = u*autoscale; v = v*autoscale; 0347 end 0348 0349 ax = newplot; 0350 next = lower(get(ax,'NextPlot')); 0351 hold_state = ishold; 0352 0353 % Make velocity vectors 0354 x = x(:).'; y = y(:).'; 0355 u = u(:).'; v = v(:).'; 0356 uu = [x;x+u;repmat(NaN,size(u))]; 0357 vv = [y;y+v;repmat(NaN,size(v))]; 0358 0359 % h1 = plot(uu(:),vv(:),[col ls]); 0360 h1 = plot(uu(:),vv(:),ls,'Color',col); 0361 0362 if plotarrows, 0363 % Make arrow heads and plot them 0364 hu = [x+u-alpha*(u+beta*(v+eps));x+u; ... 0365 x+u-alpha*(u-beta*(v+eps));repmat(NaN,size(u))]; 0366 hv = [y+v-alpha*(v-beta*(u+eps));y+v; ... 0367 y+v-alpha*(v+beta*(u+eps));repmat(NaN,size(v))]; 0368 hold on 0369 % h2 = plot(hu(:),hv(:),[col ls]); 0370 h2 = plot(hu(:),hv(:),ls,'Color',col); 0371 else 0372 h2 = []; 0373 end 0374 0375 if ~isempty(ms), % Plot marker on base 0376 hu = x; hv = y; 0377 hold on 0378 % h3 = plot(hu(:),hv(:),[col ms]); 0379 h3 = plot(hu(:),hv(:),ls,'Color',col); 0380 if filled, set(h3,'markerfacecolor',get(h1,'color')); end 0381 else 0382 h3 = []; 0383 end 0384 0385 if ~hold_state, hold off, view(2); set(ax,'NextPlot',next); end 0386 0387 if nargout>0, hh = [h1;h2;h3]; end 0388 0389 0390 0391 function retval = isscalar(m) 0392 retval = prod(size(m)) == 1;