import numpy as np import holoviews as hv from holoviews import opts from scipy.spatial import Delaunay hv.extension('bokeh') n_verts = 100 pts = np.random.randint(1, n_verts, (n_verts, 2)) tris = Delaunay(pts) trimesh = hv.TriMesh((tris.simplices, pts)) trimesh hv.TriMesh.from_vertices(np.random.randn(100, 2)) trimesh.nodes + trimesh.edgepaths # First create the x and y coordinates of the points. n_angles = 36 n_radii = 8 min_radius = 0.25 radii = np.linspace(min_radius, 0.95, n_radii) angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False) angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1) angles[:, 1::2] += np.pi/n_angles x = (radii*np.cos(angles)).flatten() y = (radii*np.sin(angles)).flatten() z = (np.cos(radii)*np.cos(angles*3.0)).flatten() nodes = np.column_stack([x, y, z]) # Apply Delaunay triangulation delaunay = Delaunay(np.column_stack([x, y])) # Mask off unwanted triangles. xmid = x[delaunay.simplices].mean(axis=1) ymid = y[delaunay.simplices].mean(axis=1) mask = np.where(xmid*xmid + ymid*ymid < min_radius*min_radius, 1, 0) simplices = delaunay.simplices[np.logical_not(mask)] nodes = hv.Points(nodes, vdims='z') hv.TriMesh((simplices, nodes)) trimesh = hv.TriMesh((simplices, nodes)) trimesh.opts( opts.TriMesh(cmap='viridis', edge_color='z', filled=True, height=400, inspection_policy='edges', tools=['hover'], width=400))