# How to use quiver correctly?

41 views (last 30 days)

Show older comments

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

##### 0 Comments

### Answers (3)

KSSV
on 6 Oct 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 Comments

William Rose
on 6 Oct 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.

William Rose
on 6 Oct 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')

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 Comments

William Rose
on 7 Oct 2022

William Rose
on 6 Oct 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.

##### 0 Comments

### See Also

### Categories

### Community Treasure Hunt

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

Start Hunting!