I have U and V wind component data and I would like to calculate wind direction from these values in R.
I would like to end up with wind direction data on a scale o
In Python:
Dir=np.mod(180+np.rad2deg(np.arctan2(U, V)),360)
This leads to a Southerly wind (180 degrees) for a [0,1] vector, a Northerly wind (0 degrees) for a [0,-1] vector, a South Westerly wind (225 degrees) for a [1,1] vector:
U
Out[86]:
array([[ 0. ],
[ 0. ],
[ 1. ],
[-3.47]])
V
Out[87]:
array([[ 1. ],
[-1. ],
[ 1. ],
[-1.47]])
np.mod(180+np.rad2deg(np.arctan2(U, V)),360)
Out[89]:
array([[180. ],
[ 0. ],
[225. ],
[ 67.04097233]])
While the accepted answer has the right idea it has a flaw.
As mentioned in the comments one does not need to normalize the u and v component in order to use atan2
on them.
The flaw comes when u == v == 0
and wind_abs
becomes 0.
In C# the two divisions will return infinity (in compliance to IEEE 754) and atan2 will return NaN.
When not normalizing the components atan2(0,0)
happily returns 0
.
So not only is normalizing not necessary, it also introduces an error.
Please also be aware that the most common function signature of atan2
is atan2(y, x)
-- Microsoft Excel being an exception.
There are three problems with this:
atan2
, you must normalize them, but you don't do this by multiplying m/s by pi/180
(which you did to get u_rad
and v_rad
). You should make a column of absolute windspeed (sqrt(u_ms^2 + v_ms^2)
) and take atan2(u_ms/wind_abs, v_ms/wind_abs)
. (also note that atan2 takes y component first - make sure that's what you want)atan2
will give you an answer in the unit circle coordinates, which increase counterclockwise and have a zero on the x-axis. You want an answer in cardinal coordinates which increase clockwise and have a zero on the y-axis. To convert unit circle to cardinal coordinates, you must subtract the unit circle angle from 90.If you are given u_ms = = -3.711
and v_ms = -1.471
(on the unit circle it is blowing down and slightly to the left, so it is coming from the northeast), then:
wind_abs = sqrt(u_ms^2 + v_ms^2)
wind_dir_trig_to = atan2(u_ms/wind_abs, v_ms/wind_abs)
wind_dir_trig_to_degrees = wind_dir_trig_to * 180/pi ## -111.6 degrees
Then you must convert this wind vector to the meteorological convention of the direction the wind is coming from:
wind_dir_trig_from_degrees = wind_dir_trig_to_degrees + 180 ## 68.38 degrees
Then you must convert that angle from "trig" coordinates to cardinal coordinates:
wind_dir_cardinal = 90 - wind_dir_trig_from_degrees
[1] 21.62284 #From the northeast.