Triangle meshes are a common form of data when working with complex polygons and are frequently employed in environmental modeling. The most common way to compute such a mesh is using Delaunay triangulation and the data is usually represented as two data structures:
This representation is in fact simply a specific type of graph and closely follow the data structures we already use for graphs, where the simplices represent the abstract connectivity of the mesh and the nodes represent the positions. It was therefore trivial to write a
Here is a simple example:
import param import numpy as np import holoviews as hv from scipy.spatial import Delaunay from holoviews.element.graphs import Graph, EdgePaths hv.extension('bokeh') n_verts = 1000 pts = np.random.randint(1, n_verts, (n_verts, 2)) tris = Delaunay(pts) hv.TriMesh((tris.simplices, tris.points))
This approach is reasonably fast for small meshes (~1 second/5000 triangles) and once you start plotting more than ~10k triangles you will want to use datashader anyway. It is also flexible enough to associate additional values both with the simplices and with the nodes.
Once holoviz/datashader#525 is merged I will get on with allowing datashader operation such as aggregate to operate on the TriMesh element.
Using this branch I am trying to get something similar, but it's not getting better:
%%output size=200 %%opts TriMesh (node_size=0 edge_line_width=0.1 edge_nonselection_alpha=0.01) plot * hv.TriMesh((tris.simplices, points))
I am unable to set the
Another question, the
Looks like you're using the matplotlib backend but specifying bokeh options, try changing that to
Have a look at the example notebook, the last example demonstrates it. Going to be pushing a small fix for that shortly.
How can I use the interpolation here?
How do I go from:
%%opts TriMesh [filled=True edge_color_index='z'] (cmap='viridis' node_alpha=0 edge_line_alpha=0.4) def plot_TriMesh(learner): ip = learner.ip() simplices = ip.tri.simplices nodes = ip.tri.points z = ip.values[simplices].mean(axis=1) return hv.TriMesh((np.column_stack([simplices, z]), nodes), vdims='z') plot_TriMesh(learner)
I would like to know because:
%timeit plot_TriMesh(learner) 2.71 ms ± 309 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) %timeit learner.plot(triangles_alpha=0.4) 216 ms ± 13.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
For the same reason
Would it be easy to make this work with
My data is calculated and plotted live, and in be beginning there might not be data to plot yet.
Then I could write beautiful things like:
if self.data: x = y = np.linspace(-0.5, 0.5, n) ip = self.ip() z = ip(x[:, None], y[None, :]) image = hv.Image(z, bounds=lbrt) tris = hv.TriMesh((ip.tri.simplices, self.unscale(ip.tri.points))) tris = tris.opts(style=dict(edge_line_alpha=triangles_alpha)) plot = image * (tris if triangles_alpha else hv.TriMesh((, ))) else: plot = hv.Image() * hv.TriMesh((, ))