Tuesday, July 13, 2010

myquiver

function myquiver(x,y,u,v,varargin)
% customized quiver plotting
% usage:
%        myquiver(x,y,u,v,[properties])
%
%                  scale: The ratio between velocity and the coordinate
%                         if a reference vector is set by 'length' without a 'scale',
%                         the code will calculate one based on the max vector from the input
%               iscenter: set the grid-points to be the mid-point of each vector, no value needed for IsCenter
%
% *************************  for reference vector  **************************
%                 length: reference vector
%                   xref: x-position of the reference vector
%                   yref: y-position of the reference vector
%                   unit: the unit of vector field, default is "m/s"
%                  noref: turn off the reference vector
%
% *************************  for arrow appreance, not necessary to change  **********************
%               location: the location arrowhead
%                         the smaller the closer to the ending point, any float value in [0,2]
%              arrowtype: control the arrow type, any float value in [0,2]
%                  width: control the width of arrowhead relative to the length of each vector
%              linecolor: control the arrow line color
%              fillcolor: fill the arrowhead with specified color
%              
% example:
%        [x,y] = meshgrid(-2:.2:2,-1:.15:1);
%        z = x .* exp(-x.^2 - y.^2); [px,py] = gradient(z,.2,.15);
%        myquiver(x,y,px,py,'length',0.8,'xref',0,'yref',1.2)
%     or
%        run it without any argument for the demo
% NOTE:
%       1: For comparison, e.g., vector fields in different months, need keep the same x- & y-limits and 'scale' values when do plotting
%       2: No projection considered here
%  Copyright: http://scriptdemo.blogspot.com

if nargin==0 % demo case
   figure; axis equal;xlim([-1.5 3.5]); ylim([-1.5 3.5]);
   myquiver(1,1,2,0,'scale',0.5,'location',0.5,'arrowtype',1,'length',0.5);
  
   myquiver(1,1,2*cos(pi/4),2*sin(pi/4),'noref','scale',0.5,'location',0.5,'arrowtype',1.5);
   myquiver(1,1,0,2,'noref','scale',0.5,'location',0.5,'arrowtype',2);
   myquiver(1,1,-2*cos(pi/4),2*sin(pi/4),   ....
                'noref','scale',0.5,'location',0.5,'arrowtype',1.5,'linecolor','k','fillcolor',[0.3 0.3 0.3]); 
  
   myquiver(1,1,-2,0,'noref','scale',0.5,'location',0.4,'arrowtype',1,'fillcolor',[0.3 0.3 0.3]);
   myquiver(1,1,-sqrt(2),-sqrt(2),'noref','scale',0.5,'location',0.25,'arrowtype',1,'fillcolor',[0.3 0.3 0.3]);
  
   myquiver(1,1,      0,      -2,'noref','scale',0.5,'location',0.5,'arrowtype',0.75,'linecolor','k','fillcolor',[0.3 0.3 0.3]);
   myquiver(1,1,sqrt(2),-sqrt(2),'noref','scale',0.5,'location',0.5,'arrowtype',0.25,'linecolor','k');
   title('Arrows Types');
  
   figure;
   [x,y] = meshgrid(-2:.2:2,-1:.15:1);
   z = x .* exp(-x.^2 - y.^2);
   [u,v] = gradient(z,.2,.15);
   subplot(2,2,1);xlim([-3 3]); ylim([-1.5 1.5]);myquiver(x,y,u,v,'scale',0.15,'length',0.5,'arrowtype',0.75,'location',1,'linecolor','r','fillcolor','k');
     subplot(2,2,2);xlim([-3 3]); ylim([-1.5 1.5]);myquiver(x,y,u,v,'scale',0.15,'length',1.0,'arrowtype',0.5,'location',0.5)
   subplot(2,2,3);xlim([-3 3]); ylim([-1.5 1.5]);
   myquiver(x,y,u,v,'scale',0.15,'length',1.0,'arrowtype',0.5,'location',0.5,'xref',0,'yref',1.2); grid on;
   xlabel('Origin from the Grid-points')
   subplot(2,2,4);xlim([-3 3]); ylim([-1.5 1.5]);
   myquiver(x,y,u,v,'scale',0.15,'length',1.0,'arrowtype',0.5,'location',0.5,'xref',2.5,'yref',0,'IsCenter'); grid on;
   xlabel('Grid-points Centered'); set(gcf,'color','w');box on;
   return
elseif nargin<4
   help myquiver
   return
end

% default setting for arrow type & size
fscale=0.15;    % control the ratio between velocity and the coordinate
myloc=0.75;     % control the location of (xm,ym)
                % the smaller, the closer to the head,[0~2]
mysize=1;       % control the arrow type [0~2]
mywidth=0.25;   % control the width of arrow
unitstr='m/s';
IsFill=0; IsLineC=0; IsScaleFix=0; IsAmp=0; BoxOn=0; IsCenter=0;
IsRef=1;

% check input arguments
while(size(varargin,2)>0)
   switch lower(varargin{1})
     case 'scale'
          fscale=varargin{2};
          varargin(1:2)=[];
          IsScaleFix=1;
     case 'length'
          mylength=varargin{2};
          varargin(1:2)=[];
     case {'fillcolor','fcolor'}
          IsFill=1;
          FillC=varargin{2};
          varargin(1:2)=[];
     case {'linecolor','lcolor'}
          IsLineC=1;
          LineC=varargin{2};
          varargin(1:2)=[];
     case 'location'
          myloc=varargin{2};
          varargin(1:2)=[];
     case 'width'
          mywidth=varargin{2};
          varargin(1:2)=[];
     case 'arrowtype'
          mysize=varargin{2};
          varargin(1:2)=[];
     case 'unit'
          unitstr=varargin{2};
          varargin(1:2)=[];
     case 'noref'
          IsRef=0;
          varargin(1)=[];
     case 'xref'
          refx0=varargin{2};
          IsRef=1;
          varargin(1:2)=[];
     case 'yref'
          refy0=varargin{2};
          IsRef=1;
          varargin(1:2)=[];
     case {'box','boxon'}
          BoxOn=1;
          varargin(1)=[];
     case 'fancy'
          IsAmp=1;
          varargin(1)=[];
     case {'iscenter'}
          IsCenter=1;
          varargin(1)=[];
     otherwise
          error(['Not defined properties!',varargin{1}])
   end
end

if exist('mylength','var')
   if ~IsScaleFix
      xdiffmax=abs(max(max(diff(x,1,2))));
      ydiffmax=abs(max(max(diff(y))));
      fscale=sqrt(xdiffmax*xdiffmax+ydiffmax*ydiffmax)/mylength;
      disp(['Current scale=',num2str(fscale)])
   end
else
   mylength=sqrt(max(max(u.*u+v.*v)))/2;
end

if ~ishold
    hold on;
end
if (IsAmp==1)
   hpcolor=pcolor(x,y,sqrt(u.*u+v.*v));
   set(hpcolor,'linestyle','none'); colorbar;
end
x=reshape(x,1,[]); y=reshape(y,1,[]);
u=reshape(u,1,[]); v=reshape(v,1,[]);
if (IsCenter)
   x0=x-u*fscale; x1=x+u*fscale;
   y0=y-v*fscale; y1=y+v*fscale;
else
   x0=x; x1=x+u*fscale*2; x=x+u*fscale;
   y0=y; y1=y+v*fscale*2; y=y+v*fscale;
end
x=x1-(x1-x0)*myloc*0.5;
y=y1-(y1-y0)*myloc*0.5;
x3=x+mywidth*(y-y1); x4=x+mywidth*(y1-y);
y3=y+mywidth*(x1-x); y4=y+mywidth*(x-x1);

xm=x1+mysize*(x-x1); ym=y1+mysize*(y-y1);
xx=[x0;xm;x3;x1;x4; xm;x1+nan]; clear x0 x1 x3 x4 xm
yy=[y0;ym;y3;y1;y4; ym;y1+nan]; clear y0 y1 y3 y4 ym
if (IsFill==1)
   hpl=plot(reshape(xx([1 2 end],:),[],1),reshape(yy([1 2 end],:),[],1),'k-');
else
   hpl=plot(xx(:),yy(:),'k-');
end
if (IsLineC==1)
    set(hpl,'color',LineC);
end
if (IsFill==1)
   xx(1,:)=[]; xx(end,:)=[];
   yy(1,:)=[]; yy(end,:)=[];
   for NL=1:size(xx,2)
       hh=patch(xx(:,NL),yy(:,NL),FillC);
       set(hh,'linestyle','none');
   end
end

% reference vector
if (IsRef)
   myxl=get(gca,'xlim'); myyl=get(gca,'ylim');
   reflength=2*fscale*mylength;
   refheady=mywidth*2*fscale*mylength*myloc*0.5;
   if ~exist('refx0','var')
      refx0=myxl(2)-reflength-0.05*diff(myxl);
   end
   refx1=refx0+reflength;
   if ~exist('refy0','var')
      refy0=myyl(1)+refheady+0.05*diff(myyl);
   end
   refy1=refy0;
   refx=refx1-(refx1-refx0)*myloc*0.5; refy=refy1;
   refx3=refx;refx4=refx;
   refy3=refy+mywidth*(refx1-refx); refy4=refy+mywidth*(refx-refx1);
   refxm=refx1+mysize*(refx-refx1); refym=refy1+mysize*(refy-refy1);
   if (BoxOn)
      xbox0=refx0-(reflength)*0.1;
      xbox1=refx1+(reflength)*0.1;
      ybox0=refy0-refheady*3;
      ybox1=refy0+refheady*3;
      plot([xbox0 xbox1 xbox1 xbox0 xbox0],[ybox0 ybox0 ybox1 ybox1 ybox0],'k-')
   end
   htxt=text(refx0,refy0,[num2str(mylength),' ',unitstr]);
   set(htxt,'fontangle','normal','fontweight','bold','HorizontalAlignment','left','VerticalAlignment','bottom');
  
   refxx=[refx0;refxm;refx3;refx1;refx4; refxm]; clear refx0 refx1 refx3 refx4 refxm
   refyy=[refy0;refym;refy3;refy1;refy4; refym]; clear refy0 refy1 refy3 refy4 refym
   plot(refxx(:),refyy(:),'k-'); hold on;
   if (IsFill)
       hhp=patch(refxx(2:6),refyy(2:6),'k');
       set(hhp,'linestyle','none');
   end
end

No comments:

ShowCalendar