holoviz / hvplot

A high-level plotting API for pandas, dask, xarray, and networkx built on HoloViews
https://hvplot.holoviz.org
BSD 3-Clause "New" or "Revised" License
1.02k stars 99 forks source link

Orthographic projection not working with rasterize=True #1194

Open morf1102 opened 8 months ago

morf1102 commented 8 months ago

I'm not sure if this is a bug or if I'm doing something wrong, but when I try to use cartopy's crs.Orthographic() projection, I get this warning:

/mamba/envs/viz/lib/python3.10/site-packages/datashader/glyphs/quadmesh.py:659: RuntimeWarning: invalid value encountered in cast
  xs = (xscaled * plot_width).astype(int)
/mamba/envs/viz/lib/python3.10/site-packages/datashader/glyphs/quadmesh.py:660: RuntimeWarning: invalid value encountered in cast
  ys = (yscaled * plot_height).astype(int)
/mamba/envs/viz/lib/python3.10/site-packages/datashader/glyphs/quadmesh.py:659: RuntimeWarning: invalid value encountered in cast
  xs = (xscaled * plot_width).astype(int)
/mamba/envs/viz/lib/python3.10/site-packages/datashader/glyphs/quadmesh.py:660: RuntimeWarning: invalid value encountered in cast
  ys = (yscaled * plot_height).astype(int)

And my map looks like this:

image


However, if I remove rasterize=True, everything seems to work:

image


Here's the code I used to create the first map:

import hvplot.xarray
import numpy as np
import xarray as xr
from cartopy import crs

ds = xr.tutorial.open_dataset('ersstv5').isel(time=0)["sst"]

ds.hvplot.quadmesh(
    project=True,
    geo=True,
    rasterize=True,
    dynamic=True,
    projection=crs.Orthographic(),
)

Versions:

ahuang11 commented 8 months ago

Thanks for reporting this.

Do you need to specifically use QuadMesh? If not, a workaround is just using an image:

import hvplot.xarray
import numpy as np
import xarray as xr
from cartopy import crs

ds = xr.tutorial.open_dataset('air_temperature').isel(time=0)

ds.hvplot(
    project=True,
    rasterize=True,
    projection=crs.Orthographic(central_longitude=-88),
    coastline=True,
    global_extent=True,
)

Seems like a bug in hvplot:

import numpy as np
import xarray as xr
import geoviews as gv
from cartopy import crs
from holoviews.operation.datashader import rasterize
import panel as pn

gv.extension("bokeh")

ds = xr.tutorial.open_dataset("air_temperature").isel(time=0)

pn.panel(rasterize(
    gv.QuadMesh(ds, ["lon", "lat"], ["air"], crs=crs.PlateCarree())
).opts("Image", projection=crs.Orthographic(central_longitude=-88), global_extent=True, tools=["hover"])).show()
ahuang11 commented 8 months ago

Okay, seems like a bug with project=True + rasterize=True

import hvplot.xarray
import numpy as np
import xarray as xr
from cartopy import crs

ds = xr.tutorial.open_dataset('air_temperature').isel(time=0)

ds.hvplot.quadmesh(
    geo=True,
    rasterize=True,
    dynamic=True,
    projection=crs.Orthographic(),
)

This seems to work.

morf1102 commented 7 months ago

Without project=True, it works until move the plot or zoom in. If I do, half of the map goes blank like this:

image
ahuang11 commented 7 months ago

Huh, I remember encountering this before... but I forget if there was a work around. Maybe @Hoxbro remembers?

Seems to break with geoviews too:

import numpy as np
import xarray as xr
import geoviews as gv
from cartopy import crs
from holoviews.operation.datashader import rasterize
import panel as pn

gv.extension("bokeh")

ds = xr.tutorial.open_dataset("air_temperature").isel(time=0)

rasterize(
    gv.QuadMesh(ds, ["lon", "lat"], ["air"], crs=crs.PlateCarree())
).opts("Image", projection=crs.Orthographic(central_longitude=-88), global_extent=True, tools=["hover"])
hoxbro commented 7 months ago

Maybe @Hoxbro remembers?

I haven't seen this before, so unfortunately, there is no help from me :slightly_frowning_face:

morf1102 commented 7 months ago

Quadmesh would be better, but using an image seems to work for now. Thanks @ahuang11 for your help!