How to use quiver correctly?

I have data include speed,direction(0-360 degree) and time series.((see attached 'quiver_input.csv')
I do not know how to apply quiver to my current data correctly.
I use the code as below:
filename = 'quiver_input.csv';
delimiter = ',';
startRow = 1;
formatSpec = '%s%f%f%f%[^\n\r]';
fileID = fopen(filename,'r');
dataArray = textscan(fileID, formatSpec, 'Delimiter', delimiter, 'EmptyValue' ,NaN,'headerlines', startRow-1,'ReturnOnError', false);
fclose(fileID);
WDate = datenum(dataArray{1});
Spd = dataArray{2};
Dir=dataArray{3};
Spd(isnan(Spd)) = 0;
Dir(isnan(Dir)) = 0;
t = WDate;
u = Spd.*cos(Dir);
v = Spd.*sin(Dir);
q = quiver(t,t*0,u,v);
The stick plot is not correect.(see attached 'quiver_output.png')
All help would be greatly appreciated. Jin

Respuestas (4)

KSSV
KSSV el 6 de Oct. de 2022
T = readtable('https://in.mathworks.com/matlabcentral/answers/uploaded_files/1147075/quiver_input.csv') ;
WDate = datenum(T.(1));
Spd = T.(2) ;
Dir = T.(3) ;
Spd(isnan(Spd)) = 0;
Dir(isnan(Dir)) = 0;
t = WDate;
u = Spd.*cosd(Dir);
v = Spd.*sind(Dir);
q = quiver(t,t*0,u,v);

6 comentarios

Jin Hung
Jin Hung el 6 de Oct. de 2022
Thanks for your answer. The requirement is to create stick plot as attachment(GMT_output.png) .
It is created by The Generic Mapping Tools.
Can you tell me is it possible to use MatLab achieve ? Thanks,
@Jin Hung, Your data has four columns. Column 1= time stamp, col.2=wind speed, col.3=wind direction (degrees). What is in column 4? The reason I am asking is that quiver plots each arrow with its base at a specified x,y location. @KSSV uses the time stamp as the x-cooridnate for each arrow, which make sense to me. Since there is no obvious y-coordimate to use for each arrow, @KSSV used zero as the y cooridmate for all the arrows. Could column 4 be a good y coordinate for locating the arrows?
I like @KSSV's code, so I gave it a thumbs up vote. You can too. And you can accept @KSSV's answer.
_____
A problem with quiver, when the x and y axis units are incommensurate, or when there are no y axis values (as in this case), is that the arrows can get distorted. This is happening with your data above. The skewed arrowheads indicate that this is occurring.
Example: Plot a wind rose (8 wind vectors of equal length, pointing in the cardinal directions) at 1 hour intervals from midnight to 0300. The wind speed is 10 m/s.
hours=[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,...
2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3];
wdate=datenum(2022,10,06,0,hours,0);
wspd=10; %wind speed, m/s
wdir=repmat(0:45:315,[1,4]); %wind direction, degrees
v=wspd*cosd(wdir); %y-component of wind
u=wspd*sind(wdir); %x-component of wind
x=wdate;
quiver(x,0*x,u,v);
The arrows that should pointing at 45,135,225,315 degrees are not. The N and S arrows are longer than the E and W arrows. This should not be. The uneven shape of the arrowheads at 45, 135, etc. is an indicator that the arrows are distorted.
Jin Hung
Jin Hung el 6 de Oct. de 2022
@William Rose the column 4 is Max Wind Speed. I am beginner of Matlab. Thanks for your information.
You can fix the problem of unequal scaling of u an v with "axis equal" after quiver:
hours=[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,...
2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3];
wdate=datenum(2022,10,06,0,hours,0);
wspd=10; %wind speed, m/s
wdir=repmat(0:45:315,[1,4]); %wind direction, degrees
v=wspd*cosd(wdir); %y-component of wind
u=wspd*sind(wdir); %x-component of wind
x=wdate;
quiver(x,0*x,u,v); axis equal;
With the "axis equal" command, the wind roses look circular, which is good. But the y-axis scale does not correctly indicate the wind speed. The y-axis values suggest the wind speed is 0.0004, but it is really 10. Disabling autoscaling in quiver does not help. See plot below, in which autoscaling has been disabled.
quiver(x,0*x,u,v,1); axis equal;
Jin Hung
Jin Hung el 6 de Oct. de 2022
@William Rose I am confused why "v=wspd*cosd(wdir); %y-component of wind" , does it be v=wspd*sind(wdir);?
William Rose
William Rose el 6 de Oct. de 2022
I use v=wspd*cosd(wdir) because in quiver, v is the y component (up down) and u is the x component (right left). When wdir=0, I want a vector with u=0, v=wdir, i.e. a straight up vector. When wdir=90, I want a u=wdir, v=0, i.e. vector pointing right.
The basic issue is that compasses have 0 degrees on the y axis, but our convention for measuring angles on the plane is put zero on the +x axis.

Iniciar sesión para comentar.

William Rose
William Rose el 6 de Oct. de 2022
The code below makes a plot like the plot you posted, which you said you want to mimic.
This code does not use quiver, because of the problems with quiver which I demonstrated in my previous answer.
%T = readtable('quiver_input.csv');
T = readtable('quiver_input2.csv'); %shorter file for testing
Spd = T.(2) ;
Dir = T.(3) ;
N=length(Spd); %number of values
Spd(isnan(Spd)) = 0;
Dir(isnan(Dir)) = 0;
u = Spd.*sind(Dir);
v = Spd.*cosd(Dir);
subplot(211), plot(T.(1),Spd,'-b'); ylabel('Speed')
subplot(212), plot(T.(1),Dir,'b.'); ylabel('Direction'); ylim([0 360])
figure;
t = tiledlayout(1,1);
ax1 = axes(t);
%The next plot is made to generate an x-axis. The data is not important.
plot(ax1,T.(1),zeros(size(T.(1))),'-w') %white for invisible data
ax1.YAxisLocation = 'right'; %y-axis 1 on right
ax1.YColor = 'w'; %white to hide y-axis 1
ax1.XColor = 'k'; %x-axis 1 is at bottom and is black
ax2 = axes(t); %create a second pair of axes
% Choose xaxmax to get approximately equal scaling for u and v.
% The factor 2.4 below is derived as follows:
% I expect the y range (for v values) to be 2*max(abs(v)), because I expect the
% most negative and most positive v values will be apprximately equal,
% for a large wind sample. I want x range ~= 1.2 times yrange,
% because Matlab plots seem to be about 20% longer than tall. Therefore this
% choice for xmax will give approximately equal scaling to x and y.
% This will cause wind vectors to be plotted at their true angles.
% I will use axis equal to to make sure the scalin is exactly equal.
% This initial guess for x range gets me in the right ballpark.
xaxmax=2.4*max(abs(v));
x=0:xaxmax/(N-1):xaxmax; %N equally spaced values
for i=1:N %loop to plot the wind arrows
plot([x(i),x(i)+u(i)],[0,v(i)],'-k')
hold on
end
axis equal %assure u,v have equal scaling
xlim([0,xaxmax]); %range of x values must line up with date-times
ax2.XAxisLocation = 'top'; %x axis 2 on top
ax2.XColor = 'w'; %white to hide x-axis 2
ax2.YAxisLocation = 'left'; %y axis 2 at left, color=black by default
ax1.Box = 'off';
ax2.Box = 'off';
ylabel('Wind Speed')
I have used ideas from this page and this page.
Compare the wind speed and direction in the top pair of plots to the wind vectors in the bottom plot. They are consistent.
Wind vectors at the left and right edges may be cut off. A possible cure for this would be to add some wind values of zero for dates before and dates after the date range plotted, before making the plot. This would expand the plotting region horizontally and result in less cut off at left and right edges.

7 comentarios

Jin Hung
Jin Hung el 6 de Oct. de 2022
@William Rose It is amazing. I am thinking of learning GMT for the requirement. I will try my best to understand your solution. Again thanks so much for your help.
William Rose
William Rose el 6 de Oct. de 2022
@Jin Hung, you are welcome. You can accept my answer if you wish. Good luck with your weather research!
Jin Hung
Jin Hung el 7 de Oct. de 2022
@William Rose Before accept your answer. I am trying use fig2plotly map to source input file for checking the correctness. please refer to fig2plotlyresult . Do you have any suggestion? Thanks.
William Rose
William Rose el 7 de Oct. de 2022
@Jin Hung, I looked at the figure at fig2plotlyresult . I don't know what data is shown, or what software was used to generate that plot, so I cannot comment on it. This is not the data in quiver_input.csv (1), which you posted (unless it is downsampled by some unspecified process), nor is it the data in quiver_input2.csv (2), the downsampled and shortened version of quiver_input.csv, which I posted.
  1. quiver_input.csv has 2012 wind samples, at 10 minute intervals, from 2022-09-21-1200 through 2022-10-05-1110 (13.97 days).
  2. quiver_input2.csv has 97 wind samples, at 1 hour intervals, from 2022-09-21-1200 through 2022-09-25-1200 (4.04 days).
  3. fig2plotlyresult shows 55 arrows over 15 days, i.e. sampling interval ~= 6.5 hours.
Jin Hung
Jin Hung el 7 de Oct. de 2022
@William Rose the quiver_input2.csv input data is in the url https://homepage.ntu.edu.tw/~jinhung/quiver_input2.html for your information. Thanks,
William Rose
William Rose el 7 de Oct. de 2022
Editada: William Rose el 7 de Oct. de 2022
[edit typos]
@Jin Hung. I viewed the plot of the quiver_input2 data at the site you provided. It appears that this plot was generated with my code. A careful anaysis of this plot shows that the code is working as desired. I analyzed one southwesterly wind vector near the end of the plot, because it is distinct from its neighbors. The image below shows a marked-up screenshot from https://homepage.ntu.edu.tw/~jinhung/quiver_input2.html. The u and v components on the plot are (-1.86,-2.90). The corresponding wspd and wdir in the csv file are (3.443,212.7,6.26). A simple polar to Cartesian transformtion shows that the u and v on the plot are consistent with the data in the text file. Therefore we have confirmed that the plotted u and v are correct. I also measured the pixel locations of the vector. The ratio of y pixels/x pixels=1.553, and the ratio u/v=1.559. This constitutes perfect agreement, given that the pixel numbers are rounded to integers. This indicates that plot aspect ratio is correct: a 45 degree wind vector will appear at 45 degrees on the plot. That is excellent.
We should also confirm that dates/times on the horizontal axis are correct. The thirteenth value in the file is at 2022-09-25 0000. The screen shot below shows that a vertical line from the base of the thirteenth vector intesects the date-time axis in the center of the 'Sep 25' label. This is exactly what we want and expect. I also counted across another 24 vectors and added vertical lines from the base of the (13+24)th vector and from the base of the (13+48)th vector. These correspond to 1 day and 2 days later. These vertical red lines also intersect the date-time axis in the center of the respective labels. This is excellent. It shows that the wind vectors are positioned at the correct horizontal locations on the plot.
William Rose
William Rose el 7 de Oct. de 2022
I see from the web page address for the plot that you are at NTU. Please send me a secure email by clicking on the envelope that will appear in the pop-up window when you click on the "WR" circle for my posts.

Iniciar sesión para comentar.

William Rose
William Rose el 6 de Oct. de 2022
I am mostly copying the code of @KSSV. I am trying to make a plot like the oe you want to mimic. @KSSV's code gives an arrow that points right (+x) when the direction is 0, and points up (+y) when the direction is 90. I want the opposite, so I have flipped cosd and sind. I use axis equal to prevent unequal scaling of u and v. I turn off arrowheads, since the plot you shared did not have arrowheads.
T = readtable('quiver_input.csv') ;
wdate = datenum(T.(1));
Spd = T.(2) ;
Dir = T.(3) ;
Spd(isnan(Spd)) = 0;
Dir(isnan(Dir)) = 0;
t = wdate;
u = Spd.*sind(Dir);
v = Spd.*cosd(Dir);
subplot(311)
quiver(t,t*0,u,v,'ShowArrowHead',0);
axis equal
subplot(312)
quiver(t,t*0,1e3*u,1e3*v,'ShowArrowHead',0);
axis equal %bigger wind
subplot(313)
quiver(t,t*0,u,v,1,'ShowArrowHead',0);
axis equal %turn off autoscale
None of the three plots above are aceptable, because the arrows are too short to see, and because the y-axis scale does not correctly indicate wind speed. I also tried using yyaxis right before quiver, to put the (incorrect) y axis on the right. I was hoping that then I could add an axis to correctly indicate wind speed on the left. But when you use yyaxis right and/or yyaxis left, the axis equal command does not work.

2 comentarios

indika kathaluwa weligamage
indika kathaluwa weligamage el 30 de Sept. de 2023
It is Very useful cord.
I used this. It was successful.
Many thanks
Kind Regard, INDIKA
William Rose
William Rose el 1 de Oct. de 2023
You are welcome. Thank you for your kind comment.

Iniciar sesión para comentar.

Rupak Loodh
Rupak Loodh el 3 de Ag. de 2023

0 votos

you may use scale:
scale_factor = 0.2;
quiver(t,t*0,u*scale_factor,v*scale_factor,'AutoScale','off','ShowArrowHead',1);
axis equal
grid on

1 comentario

indika kathaluwa weligamage
indika kathaluwa weligamage el 1 de Oct. de 2023
Thank your instructions. When using scale factor and axis equal is shows as following. How can we remove unnessesory graph area (x axis -150 to 150). It is important to add this plot to a report and interpritation. Highly appriciate your instructions. Iam expect as https://www.nicepng.com/ourpic/u2w7t4e6e6r5r5t4_time-series-of-36-hour-low-pass-filtered/
Kind Regard, INDIKA

Iniciar sesión para comentar.

Categorías

Más información sobre Polar Plots en Centro de ayuda y File Exchange.

Productos

Versión

R2022b

Etiquetas

Preguntada:

el 6 de Oct. de 2022

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by