Hourly variation of wind for each month, using Quiver
3 views (last 30 days)
Show older comments
I have three vectors: date (TIEMPO), Wind speed (VV) and Wind direction (DV).
I would like to combine Contour Plot and Quiver to display the anual variation of wind, yet, given that's a single point instead of a map, I don't know how to use "quiver" function without coordinates.
Here's my code:
%%TEST
clear all
load Viento_DMC
%separates time in diferent variables (year, month, day and hour)
[ANHO, MES, DIA, HORA, mn, s] = datevec(TIEMPO);
%delete useless variables
clearvars mn s fecha
%creates a datenum based only on year and month
TIEMPO2=datenum(ANHO,MES,1,0,0,0);
%gives a single date for each month of each year (in order to get how many
%months are in the dataset)
TIEMPO3=unique(TIEMPO2);
%max number of months in datafile
meses_max=numel(TIEMPO3);
%creates V and U components
U=VV.*sind(DV);
V=VV.*cosd(DV);
%Creates a daly cicle for wind speed (mean of every hour of each month)
cda=grpstats(VV, {hour(TIEMPO), TIEMPO2},'mean');
%creates a matrix for daly cicle of wind speed (24 hours x 60 months)
cda2d=reshape(cda, [meses_max,24]); %24 hours
%Creates a daly cicle U and V components
cdaU=grpstats(U, {hour(TIEMPO), TIEMPO2},'mean');
cdaV=grpstats(V, {hour(TIEMPO), TIEMPO2},'mean');
cdaDir=atan2d(cdaU,cdaV);
%creates a matrix for U and V components
cda2dDir=reshape(cdaDir, [meses_max,24]);
% create x/y grid 24x60
[x,y] = meshgrid(1:24,1:60) ;
% plot Wind speed and wind direction matrix's on xy grid with quiver
quiver( x,y,cda2d,cda2dDir)
This is how it's supposed to look:
The data it's attached. I would really apreciate any help you could give me. Thanks!
3 Comments
jonas
on 20 Aug 2018
My point was that you cannot (as far as I know) use the function hour on a double (datevec/datenum, doesn't matter). You need a datetime format. I'm still getting the same error. Can you run the code yourself?
Accepted Answer
jonas
on 20 Aug 2018
Edited: jonas
on 21 Aug 2018
This is my attempt with normalized/scaled arrows. See attachment.
load Viento_DMC
T=datetime(datevec(TIEMPO));
%%Velocity and direction
U=VV.*sind(DV);
V=VV.*cosd(DV);
Dir=atan2d(U,V);
TT=timetable(T,VV,Dir,U,V);
%%Take hourly mean (probably not necessary)
TT2=retime(TT,'hourly','mean');
%%Calculate hourly average per unique month/year (not sure if this is what you want, but easy to adjust)
[~,~,G]=unique([year(TT2.T) month(TT2.T) hour(TT2.T)],'rows');
VVm = splitapply(@nanmean,TT2.VV,G);
Um = splitapply(@nanmean,TT2.U,G);
Vm = splitapply(@nanmean,TT2.V,G);
VVm=reshape(VVm,24,numel(VVm)/24);
%%Normalize Um and Vm (UNCOMMENT TO NORMALIZE VECTORS)
for i=1:length(Um)
Umn(i)=Um(i)./norm([Um(i) Vm(i)]);
Vmn(i)=Vm(i)./norm([Um(i) Vm(i)]);
end
Um=Umn;
Vm=Vmn;
Um=reshape(Um,24,numel(Um)/24);
Vm=reshape(Vm,24,numel(Vm)/24);
%%create x/y grid 24x60
[x,y] = meshgrid(linspace(0,1,24),linspace(0,1,60)) ;
%%plot Wind speed and wind direction matrix's on xy grid with quiver
axis([0 1 0 1])
contourf(x,y,VVm');hold on
quiver(x,y,Um',Vm',0.5,'color','k')
axis([0 1 0.27 1])
%%Manipulate Labels
nLabelsY=10; %(60/nLabelsY must be integer NOT float)
[~,id,~]=unique([year(TT2.T) month(TT2.T)],'rows');
yticklabs=cellstr(datestr(TT2.T(id),'yyyy-mmm'))
set(gca,'ytick',linspace(0,1,nLabelsY),'yticklabels',{yticklabs{1:60/10:end}})
set(gca,'xtick',linspace(0,1,24),'xticklabels',sprintfc('%g',1:24))
7 Comments
More Answers (2)
Chad Greene
on 20 Aug 2018
A few points:
1. Instead of this:
[ANHO, MES, DIA, HORA, mn, s] = datevec(TIEMPO);
%delete useless variables
clearvars mn s fecha
You can simply do
[~, ~, ~, HORA, ~, ~] = datevec(TIEMPO);
which never writes the unnecessary variables.
load Viento_DMC
%separates time in diferent variables (year, month, day and hour)
[~, ~, ~, HORA, ~, ~] = datevec(TIEMPO);
%creates V and U components
U=VV.*sind(DV);
V=VV.*cosd(DV);
% Grid by day and hour: (UG and VG indicate "gridded")
[H,D,UG] = xyz2grid(HORA,round(TIEMPO),U);
VG = xyz2grid(HORA,round(TIEMPO),V);
% Get 31 day moving mean by operating down the rows:
UG = movmean(UG,31,1,'omitnan');
VG = movmean(VG,31,1,'omitnan');
figure
pcolor(H,D,hypot(UG,VG))
shading interp
cb = colorbar;
ylabel(cb,'velocidad media m s^{-1}')
caxis([0 4])
hold on
sz = [48 24];
Hr = imresize(H,sz);
Dr = imresize(D,sz);
% Scale by speed so all vectors are same length.
UGr = imresize(UG./hypot(UG,VG),sz);
VGr = imresize(VG./hypot(UG,VG),sz);
da = daspect;
quiver(Hr,Dr,UGr,VGr*da(2)/da(1),0.2,'k')
datetick('y','mmmyy','keeplimits')
I'm not sure how to make the arrows prettier. I've tried to account for the data aspect ratio (because the units of x and y axes are not the same), but the arrows are still a bit squashed. Perhaps one of the alternate quiver functions on File Exchange will solve the problem for you.
0 Comments
Emanuel Valdes
on 20 Aug 2018
1 Comment
jonas
on 20 Aug 2018
OK! Happy it worked out for you. I'm still getting the same error.
Undefined function 'hour' for input arguments of type 'double'.
Error in Prueba_Quiver (line 25) cda=grpstats(VV, {hour(TIEMPO), TIEMPO2},'mean');
From the doc: h = hour(t) returns the hour numbers of the datetime values in t. The h output is a double array the same size as t and contains integer values from 0 to 23.
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!