I have working code to interpolate a polygons vertices values below. My approach was to use a grid and scipy interpolate to get the values over the grid. I then use a QuadMesh with alpha=0 to hide the quadmesh but have enabled hover to display the values.
This works but the quadmesh covers the entire bounds of the polygon (max/min) so the values outside are masked to be Nans and I am looking for a way to turn off hover when mousing outside the polygons.
Any suggestions or am I down the wrong path?
#%%
import holoviews as hv
import numpy as np
import pandas as pd
from scipy.interpolate import LinearNDInterpolator
from shapely.geometry import Polygon, Point
# Enable bokeh plotting extension
hv.extension('bokeh')
def create_interpolated_polygon_plot(vertices, values):
# Create a Shapely polygon
poly = Polygon(vertices)
# Create a LinearNDInterpolator
interp = LinearNDInterpolator(vertices, values)
# Function to generate interpolated values
def interpolate_values(xs, ys):
points = np.column_stack([xs, ys])
return interp(points)
# Get bounding box of the polygon
minx, miny, maxx, maxy = poly.bounds
# Create a grid of points
x = np.linspace(minx, maxx, 100)
y = np.linspace(miny, maxy, 100)
xx, yy = np.meshgrid(x, y)
# Create a mask for points inside the polygon
points = np.column_stack([xx.ravel(), yy.ravel()])
mask = np.array([poly.contains(Point(p)) for p in points])
# Interpolate values for all points
zz = interpolate_values(xx.ravel(), yy.ravel())
# Apply the mask
zz[~mask] = np.nan
zz = zz.reshape(xx.shape)
# Create the heatmap using HoloViews QuadMesh
heatmap = hv.QuadMesh((x, y, zz)).opts(
alpha=0,
width=500,
height=500,
title='Interpolated Values Heatmap',
tools=['hover'],
clipping_colors={'NaN': 'transparent'}
)
# Create the polygon outline
polygon_outline = hv.Polygons([vertices]).opts(
fill_alpha=0,
line_color='black',
line_width=2
)
# Create points for the vertices
vertex_points = hv.Points(
data=pd.DataFrame({
'x': [v[0] for v in vertices],
'y': [v[1] for v in vertices],
'z': values
}),
kdims=['x', 'y'],
vdims=['z']
).opts(
color='red',
size=10,
tools=['hover'],
hover_tooltips=[('value', '@z{0.2f}')]
)
# Combine the heatmap, polygon outline, and vertex points
plot = (heatmap * polygon_outline * vertex_points).opts(
width=500,
height=500,
title='Polygon with Interpolated Values',
tools=['hover'],
)
return plot
# Example usage with a complex polygon (11 vertices)
vertices = [
(0, 0), (2, 1), (4, 0), (5, 2), (6, 1),
(5, 3), (6, 5), (4, 4), (2, 5), (1, 3), (0, 2)
]
values = [10, 25, 15, 30, 20, 35, 40, 30, 45, 25, 15]
plot = create_interpolated_polygon_plot(vertices, values)
plot
# %%