Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistency in angles between VectorField and VectorField.from_uv #767

Open
TheoMathurin opened this issue Nov 13, 2024 · 1 comment
Open

Comments

@TheoMathurin
Copy link

TheoMathurin commented Nov 13, 2024

Software Version Info
geoviews 1.13.0
holoviews 1.19.1

The resulting arrows are not the same if you use the usual gv.Vectorfield constructor or .from_uv. The latter yields incorrect results.

I think it may be due to a projection applied where it should not (maybe related to #296).

For hv.VectorField (holoviews instead of geoviews), that's the other way around (.from_uv is correct).

Another difference is that gv.VectorField.from_uv cannot take a crs argument like gv.VectorField.

Given components u and v, I compute the angle as np.pi/2 - np.arctan2(-v, -u)

import panel as pn
import holoviews as hv
import geoviews as gv

import numpy as np
from cartopy import crs as ccrs

hv.extension('bokeh')

x = np.linspace(-180, 180, 20)
y = np.linspace(-90, 90, 20)

X, Y = np.meshgrid(x, y)

u = 10*np.ones_like(X)
v = np.zeros_like(Y)
projection = ccrs.PlateCarree()
magnitude = np.sqrt(u**2 + v**2)
angle = np.pi/2 - np.arctan2(-v, -u)

vectorfield = gv.VectorField((X, Y, angle, magnitude))
vectorfield2 = gv.VectorField.from_uv((X, Y, u, v))
vectorfield3 = hv.VectorField((X, Y, angle, magnitude))
vectorfield4 = hv.VectorField.from_uv((X, Y, u, v))

plot1 = vectorfield.opts(title='gv.VectorField', projection=projection)  # Same issue if you don't project
plot2 = vectorfield2.opts(title='gv.VectorField.from_uv', projection=projection)  # Same issue if you don't project
plot3 = vectorfield3.opts(title='hv.VectorField')
plot4 = vectorfield4.opts(title='hv.VectorField.from_uv')
# gv
pn.Row(plot1, plot2).servable()
# hv
# pn.Row(plot3, plot4).servable()

Result with geoviews:
Image

Result with holoviews:
Image

@TheoMathurin TheoMathurin changed the title Inconsistency in VectorField angles Inconsistency in angles between VectorField and VectorField.from_uv Nov 13, 2024
@ahuang11
Copy link
Collaborator

The related code is here if you want to help take a look:

def from_uv(cls, data, kdims=None, vdims=None, **params):
if kdims is None:
kdims = ['x', 'y']
if vdims is None:
vdims = ['u', 'v']
dataset = Dataset(data, kdims=kdims, vdims=vdims, **params)
us, vs = (dataset.dimension_values(i) for i in (2, 3))
uv_magnitudes = np.hypot(us, vs) # unscaled
# using meteorological convention (direction FROM which wind blows)
radians = np.pi / 2 - np.arctan2(-vs, -us)
# calculations on this data could mutate the original data
# here we do not do any calculations; we only store the data
repackaged_dataset = {}
for kdim in kdims:
repackaged_dataset[kdim] = dataset[kdim]
repackaged_dataset["Angle"] = radians
repackaged_dataset["Magnitude"] = uv_magnitudes
for vdim in vdims[2:]:
repackaged_dataset[vdim] = dataset[vdim]
vdims = [
Dimension('Angle', cyclic=True, range=(0, 2 * np.pi)),
Dimension('Magnitude')
] + vdims[2:]
return cls(repackaged_dataset, kdims=kdims, vdims=vdims, **params)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants