holoviz / geoviews

Simple, concise geographical visualization in Python
http://geoviews.org
BSD 3-Clause "New" or "Revised" License
577 stars 75 forks source link

central_longitude doesn't update lon tick labels #329

Open ahuang11 opened 5 years ago

ahuang11 commented 5 years ago

image

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

def sample_data(shape=(73, 145)):
    """Returns ``lons``, ``lats`` and ``data`` of some fake data."""
    nlats, nlons = shape
    ys = np.linspace(-np.pi / 2, np.pi / 2, nlats)
    xs = np.linspace(0, 2*np.pi, nlons)
    lons, lats = np.meshgrid(xs, ys)
    wave = 0.75 * (np.sin(2 * lats) ** 8) * np.cos(4 * lons)
    mean = 0.5 * np.cos(2 * lats) * ((np.sin(2 * lats)) ** 2 + 2)

    lats = np.rad2deg(ys)
    lons = np.rad2deg(xs)
    data = wave + mean

    return lons, lats, data

lons, lats, data = sample_data()

ds = xr.DataArray(data, coords={'lat': lats, 'lon': lons}, dims=('lat', 'lon'))

ds.hvplot('lon', 'lat', crs=ccrs.PlateCarree()) * gv.feature.coastline()
ds.hvplot('lon', 'lat', crs=ccrs.PlateCarree(), projection=ccrs.PlateCarree(central_longitude=180)) * gv.feature.coastline()
jorgeperezg commented 9 months ago

This issue is problematic for regional grids crossing the 180th meridian.

Using projection=ccrs.PlateCarree(central_longitude=180) shows wrong longitudes in the labels and when hovering.

Using projection=ccrs.PlateCarree() creates a thin 360 degrees long plot that looks awful. Adding global_extent=True makes the plot look a bit better but a regional grid looks tiny in a global plot.

Has anyone found a fix or a workaround for this?

ahuang11 commented 9 months ago

You could likely overwrite the ticks manually by zipping through the bad ticks with the correct ticks labels

import numpy as np
import cartopy.crs as ccrs
import xarray as xr
import geoviews as gv
import hvplot.xarray

def sample_data(shape=(73, 145)):
    """Returns ``lons``, ``lats`` and ``data`` of some fake data."""
    nlats, nlons = shape
    ys = np.linspace(-np.pi / 2, np.pi / 2, nlats)
    xs = np.linspace(0, 2*np.pi, nlons)
    lons, lats = np.meshgrid(xs, ys)
    wave = 0.75 * (np.sin(2 * lats) ** 8) * np.cos(4 * lons)
    mean = 0.5 * np.cos(2 * lats) * ((np.sin(2 * lats)) ** 2 + 2)

    lats = np.rad2deg(ys)
    lons = np.rad2deg(xs)
    data = wave + mean

    return lons, lats, data

lons, lats, data = sample_data()

ds = xr.DataArray(data, coords={'lat': lats, 'lon': lons}, dims=('lat', 'lon'))

# ds.hvplot('lon', 'lat', crs=ccrs.PlateCarree()) * gv.feature.coastline()
ds.hvplot('lon', 'lat', crs=ccrs.PlateCarree(), projection=ccrs.PlateCarree(central_longitude=180)).opts(xticks=[(0, "New Tick")]) * gv.feature.coastline()
image