Can't show hover as lon/lat degree with projection

I’m trying to let the hover show the lon and lat values using degree unit following this issue, but failed:

import xarray as xr
import hvplot.xarray
from bokeh import models

data = xr.tutorial.open_dataset("rasm").load()['Tair'].isel(time=0)
data  = data.where(data['yc']>60, drop=True)

img = data.hvplot.quadmesh('xc', 'yc', projection='NorthPolarStereo', cmap='Thermal', rasterize=True, dynamic=False, coastline=True)

hover = models.HoverTool(tooltips=[
    ("lon", "@x"),
    ("lat", "@y"),
     ("test", "@image"),



Hi @zxdawn

Could you share the or a dataset that I or someone else could use to run the example. That would make it very easy to try to help. Thanks.

Hi @Marc, I used the xarray tutorial data in the example. You can run the code directly :slight_smile:

1 Like

Ahhh :grin:

I have been looking at this problem for the last couple of days. Even though I haven’t solved the problem completely, I think I got it to a point where another person can take it over the finish line and todo this, the equation(s) from going from NorthPolarStereo coordinates to lon/lat is needed.

I have changed from hvplot to GeoViews to avoid the following warning and to be able to have dynamic=True.

WARNING:param.main: Calling the .opts method with options broken down by options group (i.e. separate plot, style and norm groups) is deprecated. Use the .options method converting to the simplified format instead or use hv.opts.apply_groups for backward compatibility.

To be able to change the Hovertool a hook is needed.

import as ccrs
import geoviews as gv
import xarray as xr
from holoviews.operation.datashader import rasterize
from bokeh.models import CustomJSHover


data = xr.tutorial.open_dataset("rasm")["Tair"].isel(time=0)
data = data.where(data["yc"] > 60, drop=True)

# `gv.project` is to fix disappearing rasterize plot when pan zooming
# Opts is to look like hvplot
# Reference:
qmeshes = rasterize(gv.project(gv.Dataset(data).to(gv.QuadMesh)))

def conversion_coords_hook(plot, element):
    # This is an example of how it could be solved.
    # The code for the conversion is just copied/pasted from the example.
    # Example:
    code = """
        const projections = Bokeh.require("core/util/projections");
        const x = special_vars.x
        const y = special_vars.y
        const coords = projections.wgs84_mercator.invert(x, y)
        return coords[%d].toFixed(2)

    plot.handles["hover"].tooltips[:2] = [
        ("wrong lon", "$x{custom}"),
        ("wrong lat", "$y{custom}"),

    plot.handles["hover"].formatters = {
        "$x": CustomJSHover(code=code % 0),
        "$y": CustomJSHover(code=code % 1),


# Adding Coastline
qmeshes * gv.feature.coastline