I have a 100x100 km grid GeoDataFrame (Mollweide) that I am plotting as a gv.Image
with classified values (8 Categories) through Holoviews/Bokeh:
# convert GeoDataFrame to xarray object
xa_dataset = gv.Dataset(grid.to_xarray(), vdims=f'{metric}_cat', crs=crs.Mollweide())
# convert to gv.Image
img_grid = xa_dataset.to(gv.Image)
# custom tooltip
hover = HoverTool(
tooltips=[
("index", "$index"),
("data (using $) (x,y)", "($x, $y)"),
("data (using @) (x,y)", "(@x, @y)"),
("canvas (x,y)", "($sx, $sy)"),
("Category", "@image"),
])
image_layer = img_grid.opts(
cmap=cmap_with_nodata,
colorbar=True,
colorbar_opts={
'formatter': formatter,
'major_label_text_align':'left'},
tools=[hover],
# optional unpack of width and height
**{k: v for k, v in optional_kwargs.items() if v is not None}
)
# combine layers and set global plotting options
gv_layers = (image_layer * gf.coastline * gf.borders).opts(
projection=crs.Mollweide(),
global_extent=True,
responsive=responsive,
finalize_hooks=[set_active_tool],
title_format=title)
I can show the Image Values as HoverTool Tooltips, the above will lead to the following tooltip:
However, to make this more usefull, I would like to show the exact values for each bin from my original GeoDataFrame, not the classified values from the image (the class reference number is shown above with Category
in the tooltip). canvas (x,y)
appears to refer to my x and y bins from my GeoDataFrame. Is it possible to make the tooltip query my original GeoDataFrame to show the exact values of each bin, not the classified ones?
I tried to create an additional bokeh.plotting.ColumnDataSource
:
grid_df = pd.DataFrame(grid[[col for col in grid.columns if col != grid._geometry_column_name]])
source = ColumnDataSource.from_df(grid_df)
But I don't know how to add this source "invisible" over the gv.Image
Layer only for the purpose of showing tooltips with exact values.
I know this is somehow against the principle of bokeh that everything what is shown must also be included in the data. But in this case, adding exact tooltip information would increase usability of the interactive plot a lot in my context.
Found the answer myself: even when using gv.Image
, I can specify additional vdims
, e.g.:
# xa_dataset from GeoDataFrame
# with additional vdims
xa_dataset = gv.Dataset(
grid.to_xarray(),
vdims=[f'{metric}_cat', 'postcount', 'usercount'],
crs=crs.Mollweide())
# convert to gv.Image
img_grid = xa_dataset.to(gv.Image)
# custom tooltip
hover = HoverTool(
tooltips=[
("Usercount", "@usercount{,f}"),
("Postcount", "@postcount{,f}")
])
I actually don't understand how these additional vdims are stored in the gv.Image
, but it works!