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

Add VectorField/WindBarbs project operation #296

Merged
merged 5 commits into from Aug 10, 2023
Merged

Add VectorField/WindBarbs project operation #296

merged 5 commits into from Aug 10, 2023

Conversation

philippjfr
Copy link
Member

@poplarShift
Copy link

As usual, terrific response time!

I believe you made a mistake in the calculation of us, vs from the angle, see my commit: project_vectors...poplarShift:project_vectors

Your fix seems fine otherwise. It does change the values of the angles though that get fed into the color mapping, so it's not ideal, but a good step in the right direction.

Geoviews:
gv_wgs

gv_np

Cartopy:
cartopy_wgs

cartopy_np

@philippjfr
Copy link
Member Author

Thanks for the fixes. I think the coloring issue is to do with the magnitudes being transformed but the color range being computed before the transformation. I'll think about how best to fix that.

@ahuang11
Copy link
Collaborator

ahuang11 commented Jul 6, 2023

import numpy as np
import geoviews as gv
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import panel as pn
from metpy.calc import wind_components, wind_direction
from metpy.units import units

gv.extension("matplotlib")
pn.extension()

x = np.linspace(10, 50, 3)
X, Y = np.meshgrid(x, x)
U, V = 10 * X, 5 * Y
angle = np.pi / 2 - np.arctan2(-V, -U)
magnitude = np.hypot(U, V)
fig = plt.figure()
ax = plt.axes(projection=ccrs.Orthographic())

ax.quiver(X, Y, U, V, transform=ccrs.PlateCarree())
ax.set_global()
ax.coastlines()

vectorfield = (
    gv.VectorField(
        (X, Y, angle, magnitude), label="Vector Field", crs=ccrs.PlateCarree()
    ).opts(
        global_extent=True,
        projection=ccrs.Orthographic(),
        magnitude="Magnitude",
        show_legend=False,
    )
    * gv.feature.coastline()
)
pn.Row(
    pn.pane.Matplotlib(fig, dpi=180, width=400, height=400),
    pn.panel(vectorfield, width=300, height=300),
)
fig = plt.figure(figsize=(6, 6))
ax = plt.axes(projection=ccrs.Orthographic())
ax.barbs(
    X,
    Y,
    U,
    V,
    transform=ccrs.PlateCarree(),
    linewidth=0.5,
    sizes=dict(emptybarb=0.25, spacing=0.2, height=0.5),
)
ax.set_global()
ax.coastlines()

windbarbs = (
    gv.WindBarbs((X, Y, angle, magnitude), crs=ccrs.PlateCarree()).opts(
        global_extent=True,
        projection=ccrs.Orthographic(),
        show_legend=False,
        linewidth=0.5,
        sizes=dict(emptybarb=0.25, spacing=0.2, height=0.5),
        fig_size=200,
    )
    * gv.feature.coastline()
)

windbarbs_uv = gv.WindBarbs.from_uv((X, Y, U, V), crs=ccrs.PlateCarree()).opts(
    global_extent=True,
    projection=ccrs.Orthographic(),
    show_legend=False,
    linewidth=0.5,
    sizes=dict(emptybarb=0.25, spacing=0.2, height=0.5),
    fig_size=200,
    )

pn.Row(
    pn.pane.Matplotlib(fig, dpi=300, width=400, height=400),
    pn.panel(windbarbs, width=400, height=400),
    pn.panel(windbarbs_uv, width=400, height=400),
)
image image

@ahuang11 ahuang11 requested a review from hoxbro July 6, 2023 16:24
@ahuang11 ahuang11 changed the title Add VectorField project operation Add VectorField/WindBarbs project operation Jul 6, 2023
@ahuang11
Copy link
Collaborator

ahuang11 commented Aug 9, 2023

I think this is ready for review.

@hoxbro
Copy link
Member

hoxbro commented Aug 10, 2023

When I look at the figures, there seem to be differences in Matplotlibs and this implementation as we move closer to the border of the globe, see:
image

Do you know why?

@ahuang11
Copy link
Collaborator

When I look at the figures, there seem to be differences in Matplotlibs and this implementation as we move closer to the border of the globe, see: image

Do you know why?

I suspect it's due to:


pivot{'tail', 'mid', 'middle', 'tip'}, default: 'tail'
The part of the arrow that is anchored to the X, Y grid. The arrow rotates about this point.

'mid' is a synonym for 'middle'.

@ahuang11
Copy link
Collaborator

Setting pivot='tail'

vectorfield = (
    gv.VectorField(
        (X, Y, angle, magnitude), label="Vector Field", crs=ccrs.PlateCarree()
    ).opts(
        global_extent=True,
        projection=ccrs.Orthographic(),
        magnitude="Magnitude",
        show_legend=False,
        pivot="tail",
    )
    * gv.feature.coastline()
)
pn.Row(
    pn.pane.Matplotlib(fig, dpi=180, width=400, height=400),
    pn.panel(vectorfield, width=300, height=300),
)

Results in the same plot:
image

@ahuang11
Copy link
Collaborator

All set.

@ahuang11 ahuang11 requested a review from hoxbro August 10, 2023 13:13
@ahuang11 ahuang11 merged commit bb5fcd2 into main Aug 10, 2023
10 checks passed
@ahuang11 ahuang11 deleted the project_vectors branch August 10, 2023 16:42
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

Successfully merging this pull request may close these issues.

VectorField does not reproject angle
4 participants